Xapp-frame, v0.8.1 Rest Subscription Creation /Query /Deletion 82/6082/1
authorarchagge <konstantinos.archangelof@nokia.com>
Wed, 14 Apr 2021 05:54:05 +0000 (08:54 +0300)
committerKonstantinos Archangelof <konstantinos.archangelof@nokia.com>
Mon, 17 May 2021 14:59:25 +0000 (17:59 +0300)
Convert RMR unittest cases to REST API based
* Fixed REST endpoint construction functionality to include correct port numbers in endpoint string
* Added a REST version of a testcase TestSubReqAndRouteUpdateNok
* Refactored ut_stub REST endpoint setting API and restored original port numbers.

Xapp-frame, v0.8.1 integration:
  * Added REST API based unit test cases

Change-Id: I0989939f4210692493de549380faa1f111d71435
Signed-off-by: Konstantinos Archangelof <konstantinos.archangelof@nokia.com>
14 files changed:
e2ap/pkg/e2ap/msg_e2ap.go
e2ap/pkg/e2ap/msg_e2ap_subscription.go
go.mod
go.sum
pkg/control/client.go
pkg/control/control.go
pkg/control/e2ap.go
pkg/control/registry.go
pkg/control/restendpoint.go [new file with mode: 0644]
pkg/control/transaction.go
pkg/control/ut_messaging_test.go
pkg/control/ut_stub_rtmgr_test.go
pkg/control/ut_test.go
pkg/teststube2ap/stubE2.go

index f4ca81a..1e3ea70 100644 (file)
@@ -224,6 +224,11 @@ const (
        E2AP_SubSeqActionTypeWait     uint64 = 1
 )
 
+var E2AP_SubSeqActionTypeStrMap = map[string]uint64{
+       "continue": E2AP_SubSeqActionTypeContinue,
+       "wait":     E2AP_SubSeqActionTypeWait,
+}
+
 const (
        E2AP_TimeToWaitZero   uint64 = 0
        E2AP_TimeToWaitW1ms   uint64 = 1
@@ -245,6 +250,27 @@ const (
        E2AP_TimeToWaitW60    uint64 = 16
 )
 
+var E2AP_TimeToWaitStrMap = map[string]uint64{
+       "zero":   E2AP_TimeToWaitZero,
+       "w1ms":   E2AP_TimeToWaitW1ms,
+       "w2ms":   E2AP_TimeToWaitW2ms,
+       "w5ms":   E2AP_TimeToWaitW5ms,
+       "w10ms":  E2AP_TimeToWaitW10ms,
+       "w20ms":  E2AP_TimeToWaitW20ms,
+       "w30ms":  E2AP_TimeToWaitW30ms,
+       "w40ms":  E2AP_TimeToWaitW40ms,
+       "w50ms":  E2AP_TimeToWaitW50ms,
+       "w100ms": E2AP_TimeToWaitW100ms,
+       "w200ms": E2AP_TimeToWaitW200ms,
+       "w500ms": E2AP_TimeToWaitW500ms,
+       "w1s":    E2AP_TimeToWaitW1s,
+       "w2s":    E2AP_TimeToWaitW2s,
+       "w5s":    E2AP_TimeToWaitW5s,
+       "w10s":   E2AP_TimeToWaitW10s,
+       "w20s":   E2AP_TimeToWaitW20s,
+       "w60s":   E2AP_TimeToWaitW60,
+}
+
 type SubsequentAction struct {
        Present    bool
        Type       uint64
@@ -262,6 +288,12 @@ const (
        E2AP_ActionTypeInvalid uint64 = 99 // For RIC internal usage only
 )
 
+var E2AP_ActionTypeStrMap = map[string]uint64{
+       "report": E2AP_ActionTypeReport,
+       "insert": E2AP_ActionTypeInsert,
+       "policy": E2AP_ActionTypePolicy,
+}
+
 type ActionToBeSetupItem struct {
        ActionId                   uint64
        ActionType                 uint64
index 8c6910e..6be0b6e 100644 (file)
 
 package e2ap
 
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+type SubscriptionRequestList struct {
+       E2APSubscriptionRequests []E2APSubscriptionRequest
+}
+
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
diff --git a/go.mod b/go.mod
index 2ea2cc8..76d405e 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,7 @@ require (
        github.com/go-openapi/swag v0.19.7
        github.com/go-openapi/validate v0.19.6
        github.com/gorilla/mux v1.7.1
+       github.com/segmentio/ksuid v1.0.3
        github.com/spf13/viper v1.4.0
        github.com/stretchr/testify v1.5.1
 )
diff --git a/go.sum b/go.sum
index df13bd9..c291a79 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -208,6 +208,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzr
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/segmentio/ksuid v1.0.3 h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY=
+github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
index 11367ed..b62044e 100644 (file)
@@ -21,13 +21,14 @@ package control
 
 import (
        "fmt"
+       "strconv"
+       "strings"
+       "time"
+
        rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
        rtmgrhandle "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client/handle"
        "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_models"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "strconv"
-       "strings"
-       "time"
 )
 
 //-----------------------------------------------------------------------------
index 02110b6..aee1158 100755 (executable)
@@ -34,6 +34,7 @@ import (
        httptransport "github.com/go-openapi/runtime/client"
        "github.com/go-openapi/strfmt"
        "github.com/gorilla/mux"
+       "github.com/segmentio/ksuid"
        "github.com/spf13/viper"
 )
 
@@ -119,7 +120,7 @@ func NewControl() *Control {
        xapp.Resource.InjectRoute("/ric/v1/test/{testId}", c.TestRestHandler, "POST")
        xapp.Resource.InjectRoute("/ric/v1/symptomdata", c.SymptomDataHandler, "GET")
 
-       go xapp.Subscription.Listen(c.SubscriptionHandler, c.QueryHandler, c.SubscriptionDeleteHandler)
+       go xapp.Subscription.Listen(c.SubscriptionHandler, c.QueryHandler, c.SubscriptionDeleteHandlerCB)
 
        if readSubsFromDb == "false" {
                return c
@@ -213,29 +214,254 @@ func (c *Control) Run() {
 //
 //-------------------------------------------------------------------
 func (c *Control) SubscriptionHandler(params interface{}) (*models.SubscriptionResponse, error) {
-       /*
-          switch p := params.(type) {
-          case *models.ReportParams:
-              trans := c.tracker.NewXappTransaction(NewRmrEndpoint(p.ClientEndpoint),"" , 0, &xapp.RMRMeid{RanName: p.Meid})
-              if trans == nil {
-                    xapp.Logger.Error("XAPP-SubReq: %s", idstring(fmt.Errorf("transaction not created"), params))
-                    return
-              }
-              defer trans.Release()
-          case *models.ControlParams:
-          case *models.PolicyParams:
-          }
-       */
-       return &models.SubscriptionResponse{}, fmt.Errorf("Subscription rest interface not implemented")
-}
-
-func (c *Control) SubscriptionDeleteHandler(s string) error {
+
+       restSubId := ksuid.New().String()
+       subResp := models.SubscriptionResponse{}
+       subResp.SubscriptionID = &restSubId
+       p := params.(*models.SubscriptionParams)
+
+       c.CntRecvMsg++
+
+       c.UpdateCounter(cSubReqFromXapp)
+
+       if p.ClientEndpoint == nil {
+               xapp.Logger.Error("ClientEndpoint == nil")
+               return nil, fmt.Errorf("")
+       }
+
+       _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*p.ClientEndpoint)
+       if err != nil {
+               xapp.Logger.Error("%s", err.Error())
+               return nil, err
+       }
+
+       restSubscription, err := c.registry.CreateRESTSubscription(&restSubId, &xAppRmrEndpoint, p.Meid)
+       if err != nil {
+               xapp.Logger.Error("%s", err.Error())
+               return nil, err
+       }
+
+       subReqList := e2ap.SubscriptionRequestList{}
+       err = c.e2ap.FillSubscriptionReqMsgs(params, &subReqList, restSubscription)
+       if err != nil {
+               xapp.Logger.Error("%s", err.Error())
+               c.registry.DeleteRESTSubscription(&restSubId)
+               return nil, err
+       }
+
+       go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId)
+
+       return &subResp, nil
+
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+
+func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription, subReqList *e2ap.SubscriptionRequestList,
+       clientEndpoint *models.SubscriptionParamsClientEndpoint, meid *string, restSubId *string) {
+
+       xapp.Logger.Info("Subscription Request count=%v ", len(subReqList.E2APSubscriptionRequests))
+
+       _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*clientEndpoint)
+       if err != nil {
+               xapp.Logger.Error("%s", err.Error())
+               return
+       }
+
+       var requestorID int64
+       var instanceId int64
+       for index := 0; index < len(subReqList.E2APSubscriptionRequests); index++ {
+               subReqMsg := subReqList.E2APSubscriptionRequests[index]
+
+               trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(xAppRmrEndpoint), *restSubId, subReqMsg.RequestId, &xapp.RMRMeid{RanName: *meid})
+               if trans == nil {
+                       c.registry.DeleteRESTSubscription(restSubId)
+                       xapp.Logger.Error("XAPP-SubReq transaction not created. RESTSubId=%s, EndPoint=%s, Meid=%s", *restSubId, xAppRmrEndpoint, *meid)
+                       return
+               }
+
+               defer trans.Release()
+               xapp.Logger.Info("Handle SubscriptionRequest index=%v, %s", index, idstring(nil, trans))
+               subRespMsg, err := c.handleSubscriptionRequest(trans, &subReqMsg, meid, restSubId)
+               if err != nil {
+                       // Send notification to xApp that prosessing of a Subscription Request has failed. Currently it is not possible
+                       // to indicate error. Such possibility should be added. As a workaround requestorID and instanceId are set to zero value
+                       requestorID = (int64)(0)
+                       instanceId = (int64)(0)
+                       resp := &models.SubscriptionResponse{
+                               SubscriptionID: restSubId,
+                               SubscriptionInstances: []*models.SubscriptionInstance{
+                                       &models.SubscriptionInstance{RequestorID: &requestorID, InstanceID: &instanceId},
+                               },
+                       }
+                       // Mark REST subscription request processed.
+                       restSubscription.SetProcessed()
+                       xapp.Logger.Info("Sending unsuccessful REST notification to endpoint=%v:%v, InstanceId=%v, %s", clientEndpoint.Host, clientEndpoint.HTTPPort, instanceId, idstring(nil, trans))
+                       xapp.Subscription.Notify(resp, *clientEndpoint)
+               } else {
+                       xapp.Logger.Info("SubscriptionRequest index=%v processed successfully. endpoint=%v, InstanceId=%v, %s", index, *clientEndpoint, instanceId, idstring(nil, trans))
+
+                       // Store successfully processed InstanceId for deletion
+                       restSubscription.AddInstanceId(subRespMsg.RequestId.InstanceId)
+
+                       // Send notification to xApp that a Subscription Request has been processed.
+                       requestorID = (int64)(subRespMsg.RequestId.Id)
+                       instanceId = (int64)(subRespMsg.RequestId.InstanceId)
+                       resp := &models.SubscriptionResponse{
+                               SubscriptionID: restSubId,
+                               SubscriptionInstances: []*models.SubscriptionInstance{
+                                       &models.SubscriptionInstance{RequestorID: &requestorID, InstanceID: &instanceId},
+                               },
+                       }
+                       // Mark REST subscription request processesd.
+                       restSubscription.SetProcessed()
+                       xapp.Logger.Info("Sending successful REST notification to endpoint=%v, InstanceId=%v, %s", *clientEndpoint, instanceId, idstring(nil, trans))
+                       xapp.Subscription.Notify(resp, *clientEndpoint)
+               }
+               c.UpdateCounter(cSubRespToXapp)
+       }
+}
+
+//-------------------------------------------------------------------
+//
+//------------------------------------------------------------------
+func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, meid *string,
+       restSubId *string) (*e2ap.E2APSubscriptionResponse, error) {
+
+       err := c.tracker.Track(trans)
+       if err != nil {
+               err = fmt.Errorf("XAPP-SubReq: %s", idstring(err, trans))
+               xapp.Logger.Error("%s", err.Error())
+               return nil, err
+       }
+
+       subs, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c)
+       if err != nil {
+               err = fmt.Errorf("XAPP-SubReq: %s", idstring(err, trans))
+               xapp.Logger.Error("%s", err.Error())
+               return nil, err
+       }
+
+       //
+       // Wake subs request
+       //
+       go c.handleSubscriptionCreate(subs, trans)
+       event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
+
+       err = nil
+       if event != nil {
+               switch themsg := event.(type) {
+               case *e2ap.E2APSubscriptionResponse:
+                       trans.Release()
+                       return themsg, nil
+               case *e2ap.E2APSubscriptionFailure:
+                       err = fmt.Errorf("SubscriptionFailure received")
+                       return nil, err
+               default:
+                       break
+               }
+       }
+       err = fmt.Errorf("XAPP-SubReq: failed %s", idstring(err, trans, subs))
+       xapp.Logger.Error("%s", err.Error())
+       c.registry.RemoveFromSubscription(subs, trans, 5*time.Second, c)
+       return nil, err
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) SubscriptionDeleteHandlerCB(restSubId string) error {
+
+       c.CntRecvMsg++
+       c.UpdateCounter(cSubDelReqFromXapp)
+
+       xapp.Logger.Info("SubscriptionDeleteRequest from XAPP")
+
+       restSubscription, err := c.registry.GetRESTSubscription(restSubId)
+       if err != nil {
+               xapp.Logger.Error("%s", err.Error())
+               if restSubscription == nil {
+                       // Subscription was not found
+                       return nil
+               } else {
+                       if restSubscription.SubReqOngoing == true {
+                               err := fmt.Errorf("Handling of the REST Subscription Request still ongoing %s", restSubId)
+                               xapp.Logger.Error("%s", err.Error())
+                               return err
+                       } else if restSubscription.SubDelReqOngoing == true {
+                               // Previous request for same restSubId still ongoing
+                               return nil
+                       }
+               }
+       }
+
+       xAppRmrEndPoint := restSubscription.xAppRmrEndPoint
+       go func() {
+               for _, instanceId := range restSubscription.InstanceIds {
+                       err := c.SubscriptionDeleteHandler(&restSubId, &xAppRmrEndPoint, &restSubscription.Meid, instanceId)
+                       if err != nil {
+                               xapp.Logger.Error("%s", err.Error())
+                               //return err
+                       }
+                       xapp.Logger.Info("Deleteting instanceId = %v", instanceId)
+                       restSubscription.DeleteInstanceId(instanceId)
+               }
+               c.registry.DeleteRESTSubscription(&restSubId)
+       }()
+
+       c.UpdateCounter(cSubDelRespToXapp)
+
        return nil
 }
 
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) SubscriptionDeleteHandler(restSubId *string, endPoint *string, meid *string, instanceId uint32) error {
+
+       trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(*endPoint), *restSubId, e2ap.RequestId{0, 0}, &xapp.RMRMeid{RanName: *meid})
+       if trans == nil {
+               err := fmt.Errorf("XAPP-SubDelReq transaction not created. restSubId %s, endPoint %s, meid %s, instanceId %v", *restSubId, *endPoint, *meid, instanceId)
+               xapp.Logger.Error("%s", err.Error())
+       }
+       defer trans.Release()
+
+       err := c.tracker.Track(trans)
+       if err != nil {
+               err := fmt.Errorf("XAPP-SubDelReq %s:", idstring(err, trans))
+               xapp.Logger.Error("%s", err.Error())
+               return &time.ParseError{}
+       }
+
+       subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{instanceId})
+       if err != nil {
+               err := fmt.Errorf("XAPP-SubDelReq %s:", idstring(err, trans))
+               xapp.Logger.Error("%s", err.Error())
+               return err
+       }
+       //
+       // Wake subs delete
+       //
+       go c.handleSubscriptionDelete(subs, trans)
+       trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
+
+       xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
+
+       c.registry.RemoveFromSubscription(subs, trans, 5*time.Second, c)
+
+       return nil
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
 func (c *Control) QueryHandler() (models.SubscriptionList, error) {
        xapp.Logger.Info("QueryHandler() called")
 
+       c.CntRecvMsg++
+
        return c.registry.QueryHandler()
 }
 
@@ -504,6 +730,7 @@ func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *Tran
                        removeSubscriptionFromDb = true
                        subRfMsg, valid = subs.SetCachedResponse(event, false)
                        xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
+                       c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
                case *SubmgrRestartTestEvent:
                        // This simulates that no response has been received and after restart subscriptions are restored from db
                        xapp.Logger.Debug("Test restart flag is active. Dropping this transaction to test restart case")
index b21eb3f..c547567 100644 (file)
@@ -29,6 +29,7 @@ import (
        "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap_wrapper"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 )
 
@@ -37,6 +38,50 @@ var packerif e2ap.E2APPackerIf = e2ap_wrapper.NewAsn1E2Packer()
 type E2ap struct {
 }
 
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (c *E2ap) FillSubscriptionReqMsgs(params interface{}, subreqList *e2ap.SubscriptionRequestList, restSubscription *RESTSubscription) error {
+       xapp.Logger.Info("FillSubscriptionReqMsgs")
+
+       p := params.(*models.SubscriptionParams)
+
+       for _, subscriptionDetail := range p.SubscriptionDetails {
+               subReqMsg := e2ap.E2APSubscriptionRequest{}
+
+               if p.RANFunctionID != nil {
+                       subReqMsg.FunctionId = (e2ap.FunctionId)(*p.RANFunctionID)
+               }
+               subReqMsg.RequestId = e2ap.RequestId{uint32(*subscriptionDetail.RequestorID), uint32(*subscriptionDetail.InstanceID)}
+
+               subReqMsg.EventTriggerDefinition.Data.Data = []byte(subscriptionDetail.EventTriggers.OctetString)
+               subReqMsg.EventTriggerDefinition.Data.Length = uint64(len(subscriptionDetail.EventTriggers.OctetString))
+
+               for _, actionToBeSetup := range subscriptionDetail.ActionToBeSetupList {
+                       actionToBeSetupItem := e2ap.ActionToBeSetupItem{}
+                       actionToBeSetupItem.ActionType = e2ap.E2AP_ActionTypeInvalid
+                       actionToBeSetupItem.ActionId = uint64(*actionToBeSetup.ActionID)
+
+                       actionToBeSetupItem.ActionType = e2ap.E2AP_ActionTypeStrMap[*actionToBeSetup.ActionType]
+                       actionToBeSetupItem.RicActionDefinitionPresent = true
+
+                       if actionToBeSetup.ActionDefinition != nil {
+                               actionToBeSetupItem.ActionDefinitionChoice.Data.Data = []byte(actionToBeSetup.ActionDefinition.OctetString)
+                               actionToBeSetupItem.ActionDefinitionChoice.Data.Length = uint64(len(actionToBeSetup.ActionDefinition.OctetString))
+
+                       }
+                       if actionToBeSetup.SubsequentAction != nil {
+                               actionToBeSetupItem.SubsequentAction.Present = true
+                               actionToBeSetupItem.SubsequentAction.Type = e2ap.E2AP_SubSeqActionTypeStrMap[*actionToBeSetup.SubsequentAction.SubsequentActionType]
+                               actionToBeSetupItem.SubsequentAction.TimetoWait = e2ap.E2AP_TimeToWaitStrMap[*actionToBeSetup.SubsequentAction.TimeToWait]
+                       }
+                       subReqMsg.ActionSetups = append(subReqMsg.ActionSetups, actionToBeSetupItem)
+               }
+               subreqList.E2APSubscriptionRequests = append(subreqList.E2APSubscriptionRequests, subReqMsg)
+       }
+       return nil
+}
+
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
index 1c6ab3d..d7f8011 100644 (file)
@@ -21,32 +21,93 @@ package control
 
 import (
        "fmt"
+       "sync"
+       "time"
+
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "sync"
-       "time"
 )
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
 
+type RESTSubscription struct {
+       xAppRmrEndPoint  string
+       Meid             string
+       InstanceIds      []uint32
+       SubReqOngoing    bool
+       SubDelReqOngoing bool
+}
+
+func (r *RESTSubscription) AddInstanceId(instanceId uint32) {
+       r.InstanceIds = append(r.InstanceIds, instanceId)
+}
+
+func (r *RESTSubscription) SetProcessed() {
+       r.SubReqOngoing = false
+}
+
+func (r *RESTSubscription) DeleteInstanceId(instanceId uint32) {
+       r.InstanceIds = r.InstanceIds[1:]
+}
+
 type Registry struct {
-       mutex       sync.Mutex
-       register    map[uint32]*Subscription
-       subIds      []uint32
-       rtmgrClient *RtmgrClient
+       mutex             sync.Mutex
+       register          map[uint32]*Subscription
+       subIds            []uint32
+       rtmgrClient       *RtmgrClient
+       restSubscriptions map[string]*RESTSubscription
 }
 
 func (r *Registry) Initialize() {
        r.register = make(map[uint32]*Subscription)
+       r.restSubscriptions = make(map[string]*RESTSubscription)
+
        var i uint32
        for i = 1; i < 65535; i++ {
                r.subIds = append(r.subIds, i)
        }
 }
 
+func (r *Registry) CreateRESTSubscription(restSubId *string, xAppRmrEndPoint *string, maid *string) (*RESTSubscription, error) {
+       r.mutex.Lock()
+       defer r.mutex.Unlock()
+       newRestSubscription := RESTSubscription{}
+       newRestSubscription.xAppRmrEndPoint = *xAppRmrEndPoint
+       newRestSubscription.Meid = *maid
+       newRestSubscription.SubReqOngoing = true
+       newRestSubscription.SubDelReqOngoing = false
+       r.restSubscriptions[*restSubId] = &newRestSubscription
+       xapp.Logger.Info("Registry: Created REST subscription successfully. restSubId=%v, subscriptionCount=%v, e2apCubscriptionCount=%v", *restSubId, len(r.restSubscriptions), len(r.register))
+       return &newRestSubscription, nil
+}
+
+func (r *Registry) DeleteRESTSubscription(restSubId *string) {
+       r.mutex.Lock()
+       defer r.mutex.Unlock()
+       delete(r.restSubscriptions, *restSubId)
+       xapp.Logger.Info("Registry: Deleted REST subscription successfully. restSubId=%v, subscriptionCount=%v", *restSubId, len(r.restSubscriptions))
+}
+
+func (r *Registry) GetRESTSubscription(restSubId string) (*RESTSubscription, error) {
+       r.mutex.Lock()
+       defer r.mutex.Unlock()
+       if restSubscription, ok := r.restSubscriptions[restSubId]; ok {
+               // Subscription deletion is not allowed if prosessing subscription request in not ready
+               if restSubscription.SubDelReqOngoing == false && restSubscription.SubReqOngoing == false {
+                       restSubscription.SubDelReqOngoing = true
+                       r.restSubscriptions[restSubId] = restSubscription
+                       return restSubscription, nil
+               } else {
+                       return restSubscription, fmt.Errorf("Registry: REST delete request is still ongoing for the endpoint=%v, restSubId=%v, SubDelReqOngoing=%v, SubReqOngoing=%v", restSubscription, restSubId, restSubscription.SubDelReqOngoing, restSubscription.SubReqOngoing)
+               }
+               return restSubscription, nil
+       }
+       return nil, fmt.Errorf("Registry: No valid subscription found with restSubId=%v", restSubId)
+}
+
 func (r *Registry) QueryHandler() (models.SubscriptionList, error) {
        r.mutex.Lock()
        defer r.mutex.Unlock()
diff --git a/pkg/control/restendpoint.go b/pkg/control/restendpoint.go
new file mode 100644 (file)
index 0000000..b872c47
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+==================================================================================
+  Copyright (c) 2019 AT&T Intellectual Property.
+  Copyright (c) 2019 Nokia
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+*/
+
+package control
+
+import (
+       "fmt"
+       "strconv"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+)
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func ConstructEndpointAddresses(clientEndpoint models.SubscriptionParamsClientEndpoint) (string, string, error) {
+
+       var HTTP_port int64 = *clientEndpoint.HTTPPort
+       var RMR_port int64 = *clientEndpoint.RMRPort
+       var host string = clientEndpoint.Host
+       var xAppHTTPEndPoint string
+       var xAppRMREndPoint string
+
+       if *clientEndpoint.HTTPPort > 0 {
+               xAppHTTPEndPoint = host + ":" + strconv.FormatInt(*clientEndpoint.HTTPPort, 10)
+       }
+       if *clientEndpoint.RMRPort > 0 {
+               xAppRMREndPoint = host + ":" + strconv.FormatInt(*clientEndpoint.RMRPort, 10)
+       }
+       if host == "" || (HTTP_port == 0 && RMR_port == 0) {
+               err := fmt.Errorf("ClientEndpoint aprovided no PORT numbers")
+               return "INVALID_HTTP_ADDRESS:" + host + (string)(*clientEndpoint.HTTPPort),
+                       "INVALID_RMR_ADDRESS:" + host + (string)(*clientEndpoint.RMRPort),
+                       err
+       }
+
+       xapp.Logger.Info("xAppHttpEndPoint=%v, xAppRrmEndPoint=%v", xAppHTTPEndPoint, xAppRMREndPoint)
+
+       return xAppHTTPEndPoint, xAppRMREndPoint, nil
+}
index 570cb7a..efb630c 100644 (file)
 package control
 
 import (
-       "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
-       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        "strconv"
        "sync"
        "time"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 )
 
 //-----------------------------------------------------------------------------
index 81464b8..71bc92d 100644 (file)
@@ -105,6 +105,7 @@ func TestSubReqAndRouteNok(t *testing.T) {
 //     |             |              |              |
 //     |        [SUBS DELETE]       |              |
 //     |             |              |              |
+
 func TestSubReqAndRouteUpdateNok(t *testing.T) {
        CaseBegin("TestSubReqAndRouteUpdateNok")
 
@@ -648,6 +649,7 @@ func TestSubDelReqCollision(t *testing.T) {
 //     |          |              |              |
 //
 //-----------------------------------------------------------------------------
+
 func TestSubReqAndSubDelOkTwoParallel(t *testing.T) {
        CaseBegin("TestSubReqAndSubDelOkTwoParallel")
 
@@ -880,7 +882,6 @@ func TestSubReqRetryInSubmgr(t *testing.T) {
 //     |              |              |
 //
 //-----------------------------------------------------------------------------
-
 func TestSubReqRetryNoRespSubDelRespInSubmgr(t *testing.T) {
        CaseBegin("TestSubReqTwoRetriesNoRespSubDelRespInSubmgr start")
 
@@ -1003,6 +1004,12 @@ func TestSubReqTwoRetriesNoRespAtAllInSubmgr(t *testing.T) {
 //     |              |      SubFail |
 //     |              |<-------------|
 //     |              |              |
+//     |              | SubDelReq    |
+//     |              |------------->|
+//     |              |              |
+//     |              |   SubDelResp |
+//     |              |<-------------|
+//     |              |              |
 //     |      SubFail |              |
 //     |<-------------|              |
 //     |              |              |
@@ -1028,6 +1035,10 @@ func TestSubReqSubFailRespInSubmgr(t *testing.T) {
        fparams1.Set(crereq1)
        e2termConn1.SendSubsFail(t, fparams1, cremsg1)
 
+       // E2t: Receive SubsDelReq and send SubsDelResp (internal first)
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+
        // Xapp: Receive SubsFail
        e2SubsId := xappConn1.RecvSubsFail(t, cretrans)
 
@@ -1439,6 +1450,11 @@ func TestSubReqAndSubDelOkSameActionParallel(t *testing.T) {
 //     |             |              |    SubFail1  |
 //     |             |              |<-------------|
 //     |             |              |              |
+//     |             |              | SubDelReq    |
+//     |             |              |------------->|
+//     |             |              |   SubDelResp |
+//     |             |              |<-------------|
+//     |             |              |              |
 //     |             |    SubFail1  |              |
 //     |             |<-------------|              |
 //     |             |              |              |
@@ -1469,6 +1485,10 @@ func TestSubReqAndSubDelNokSameActionParallel(t *testing.T) {
        fparams1.Set(crereq1)
        e2termConn1.SendSubsFail(t, fparams1, cremsg1)
 
+       // E2t: internal delete
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
        //Fail1
        e2SubsId1 := xappConn1.RecvSubsFail(t, cretrans1)
        //Fail2
@@ -1940,7 +1960,8 @@ func TestSubReqNokAndSubDelOkWithRestartInMiddle(t *testing.T) {
        e2SubsId := uint32(resp[0].SubscriptionID)
        t.Logf("e2SubsId = %v", e2SubsId)
 
-       mainCtrl.SimulateRestart(t) // This will trigger sending of SubDelReq
+       mainCtrl.SimulateRestart(t)
+       xapp.Logger.Debug("mainCtrl.SimulateRestart done")
 
        delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
        e2termConn1.SendSubsDelResp(t, delreq, delmsg)
@@ -2006,6 +2027,7 @@ func TestSubReqAndSubDelOkWithRestartInMiddle(t *testing.T) {
        assert.Equal(t, resp[0].ClientEndpoint, []string{"localhost:13560"})
 
        mainCtrl.SimulateRestart(t)
+       xapp.Logger.Debug("mainCtrl.SimulateRestart done")
 
        // Check that subscription is restored correctly after restart
        resp, _ = xapp.Subscription.QuerySubscriptions()
@@ -2107,6 +2129,7 @@ func TestSubReqAndSubDelOkSameActionWithRestartsInMiddle(t *testing.T) {
        assert.Equal(t, resp[0].ClientEndpoint, []string{"localhost:13560", "localhost:13660"})
 
        mainCtrl.SimulateRestart(t)
+       xapp.Logger.Debug("mainCtrl.SimulateRestart done")
 
        // Check that subscription is restored correctly after restart
        resp, _ = xapp.Subscription.QuerySubscriptions()
@@ -2139,6 +2162,10 @@ func TestSubReqAndSubDelOkSameActionWithRestartsInMiddle(t *testing.T) {
        mainCtrl.wait_registry_empty(t, 10)
 }
 
+//*****************************************************************************
+//  REST interface test cases
+//*****************************************************************************
+
 //-----------------------------------------------------------------------------
 // Test debug GET and POST requests
 //
@@ -2152,7 +2179,6 @@ func TestSubReqAndSubDelOkSameActionWithRestartsInMiddle(t *testing.T) {
 //     |         Resp |
 //     |<-------------|
 //     |              |
-
 func TestGetSubscriptions(t *testing.T) {
 
        mainCtrl.sendGetRequest(t, "localhost:8088", "/ric/v1/subscriptions")
@@ -2172,3 +2198,2461 @@ func TestPostEmptyDb(t *testing.T) {
 
        mainCtrl.sendPostRequest(t, "localhost:8080", "/ric/v1/test/emptydb")
 }
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndRouteNok
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | rtmgr   |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | RouteCreate  |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 | RouteCreate  |
+//     |                 |  status:400  |
+//     |                 |(Bad request) |
+//     |                 |<-------------|
+//     |       RESTNotif |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |          [SUBS INT DELETE]     |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndRouteNok(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndRouteNok")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cRouteCreateFail, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+       waiter := rtmgrHttp.AllocNextEvent(false)
+       newSubsId := mainCtrl.get_registry_next_subid(t)
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       waiter.WaitResult(t)
+
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", e2SubsId)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       // Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, newSubsId, 10)
+       waitSubsCleanup(t, e2SubsId, 10)
+       mainCtrl.VerifyCounterValues(t)
+}
+
+func TestRESTSubReqAndRouteUpdateNok(t *testing.T) {
+       CaseBegin("TestSubReqAndRouteUpdateNok")
+
+       //Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cRouteCreateUpdateFail, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       //Subs Create
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       // xapp2 ROUTE creation shall fail with  400 from rtmgr -> submgr
+       waiter := rtmgrHttp.AllocNextEvent(false)
+       newSubsId := mainCtrl.get_registry_next_subid(t)
+       params = xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetMeid("RAN_NAME_1")
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for second subscriber : %v", restSubId2)
+       xappConn2.ExpectRESTNotification(t, restSubId2)
+       waiter.WaitResult(t)
+       // e2SubsId2 := xappConn2.WaitRESTNotification(t, restSubId2) - TOD: missing delete
+       xappConn2.WaitRESTNotification(t, restSubId2)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId)
+
+       mainCtrl.wait_subs_clean(t, newSubsId, 10)
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+func TestRESTSubDelReqAndRouteDeleteNok(t *testing.T) {
+       CaseBegin("TestRESTSubDelReqAndRouteDeleteNok")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cRouteDeleteFail, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       //Subs Create
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       waiter := rtmgrHttp.AllocNextEvent(false)
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+       waiter.WaitResult(t)
+
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+func TestRESTSubMergeDelAndRouteUpdateNok(t *testing.T) {
+       CaseBegin("TestRESTSubMergeDelAndRouteUpdateNok")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cRouteDeleteUpdateFail, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       //Subs Create
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+       restSubId2, e2SubsId2 := createXapp2MergedSubscription(t, "RAN_NAME_1")
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560", "localhost:13660"})
+
+       //Del1, this shall fail on rtmgr side
+       waiter := rtmgrHttp.AllocNextEvent(false)
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       waiter.WaitResult(t)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13660"})
+
+       //Del2
+       deleteXapp2Subscription(t, &restSubId2)
+
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqRetransmission
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq1     |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq1      |
+//     |                 |------------->|
+//     |                 |              |
+//     | RESTSubReq2     |              |
+//     | (retrans)       |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |                 | SubReq2      |
+//     |                 |------------->|
+//     |    RESTSubResp2 |              |
+//     |<----------------|              |
+//     |                 |     SubResp1 |
+//     |                 |<-------------|
+//     |      RESTNotif1 |              |
+//     |<----------------|              |
+//     |                 |     SubResp1 |
+//     |                 |<-------------|
+//     |      RESTNotif2 |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |            [SUBS DELETE]       |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+/*
+func TestRESTSubReqRetransmission(t *testing.T) {
+       CaseBegin("TestRESTSubReqRetransmission")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 2},
+       })
+       // Retry/duplicate will get the same way as the first request.  Submgr cannot detect duplicate RESTRequests
+       // Contianed duplicate messages from same xapp will not be merged. Here we use xappConn2 to simulate sending
+       // second request from same xapp as doing it from xappConn1 would not work as notification would not be received
+
+       // Subs Create
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // In order to force both XAPP's to create their own subscriptions, force rtmgr to block a while so that 2nd create
+       // gets into execution before the rtmgrg responds for the first one.
+       waiter := rtmgrHttp.AllocNextSleep(10, true)
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params)
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+
+       waiter.WaitResult(t)
+
+       xappConn1.WaitListedRestNotifications(t, []string{restSubId1, restSubId2})
+
+       // Depending one goroutine scheduling order, we cannot say for sure which xapp reaches e2term first. Thus
+       // the order is not significant he6re.
+       crereq, cremsg := e2termConn1.RecvSubsReq(t)
+       e2termConn1.SendSubsResp(t, crereq, cremsg)
+       crereq, cremsg = e2termConn1.RecvSubsReq(t)
+       e2termConn1.SendSubsResp(t, crereq, cremsg)
+
+       e2SubsIdA := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 1.st XAPP notification received e2SubsId=%v", e2SubsIdA)
+       e2SubsIdB := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 2.nd XAPP notification received e2SubsId=%v", e2SubsIdB)
+
+       // Del1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+
+       // Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, e2SubsIdA.E2SubsId, 10)
+
+       // Del2
+       xappConn2.SendRESTSubsDelReq(t, &restSubId2)
+       delreq2, delmsg2 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq2, delmsg2)
+
+       waitSubsCleanup(t, e2SubsIdB.E2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+func TestRESTSubDelReqRetransmission(t *testing.T) {
+       CaseBegin("TestRESTSubDelReqRetransmission")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       //Subs Create
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       //Subs Delete
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+
+       seqBef := mainCtrl.get_msgcounter(t)
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       mainCtrl.wait_msgcounter_change(t, seqBef, 10)
+
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqDelReq
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |  RESTSubDelResp |              |
+//     |     unsuccess   |              |
+//     |<----------------|              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     |      RESTNotif1 |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |            [SUBS DELETE]       |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqDelReq(t *testing.T) {
+       CaseBegin("TestRESTSubReqDelReq")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       // Del. This will fail as processing of the subscription
+       // is still ongoing in submgr. Deletion is not allowed before
+       // subscription creation has been completed.
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       crereq, cremsg := e2termConn1.RecvSubsReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsResp(t, crereq, cremsg)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+
+       // Retry del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+func TestRESTSubDelReqCollision(t *testing.T) {
+       CaseBegin("TestRESTSubDelReqCollision - not relevant for REST API")
+}
+
+func TestRESTSubReqAndSubDelOkTwoParallel(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkTwoParallel")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       //Req1
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send 1st REST subscriber request for subscriberId : %v", restSubId1)
+
+       //Req2
+       params = xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send 2nd REST subscriber request for subscriberId : %v", restSubId2)
+
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+       crereq2, cremsg2 := e2termConn1.RecvSubsReq(t)
+
+       //XappConn1 receives both of the  responses
+       xappConn1.WaitListedRestNotifications(t, []string{restSubId1, restSubId2})
+
+       //Resp1
+       e2termConn1.SendSubsResp(t, crereq1, cremsg1)
+       //Resp2
+       e2termConn1.SendSubsResp(t, crereq2, cremsg2)
+
+       e2SubsIdA := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 1.st XAPP notification received e2SubsId=%v", e2SubsIdA)
+       e2SubsIdB := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 2.nd XAPP notification received e2SubsId=%v", e2SubsIdB)
+
+       //Del1
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId1)
+       //Del2
+       deleteSubscription(t, xappConn2, e2termConn1, &restSubId2)
+
+       //Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, e2SubsIdA.E2SubsId, 10)
+       waitSubsCleanup(t, e2SubsIdB.E2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+func TestRESTSameSubsDiffRan(t *testing.T) {
+       CaseBegin("TestRESTSameSubsDiffRan")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1, e2SubsId1 := createSubscription(t, xappConn1, e2termConn1, params)
+       xapp.Logger.Info("Send 1st REST subscriber request for subscriberId : %v", restSubId1)
+
+       params = xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetMeid("RAN_NAME_2")
+       restSubId2, e2SubsId2 := createSubscription(t, xappConn1, e2termConn1, params)
+       xapp.Logger.Info("Send 2nd REST subscriber request for subscriberId : %v", restSubId2)
+
+       //Del1
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId1)
+       //Del2
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId2)
+
+       //Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, e2SubsId1, 10)
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+func TestRESTSubReqRetryInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubReqRetryInSubmgr start")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubReReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       // Catch the first message and ignore it
+       crereq, cremsg := e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore REST subscriber request for subscriber : %v", restSubId)
+
+       // The second request is being handled normally
+       crereq, cremsg = e2termConn1.RecvSubsReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsResp(t, crereq, cremsg)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId)
+
+       mainCtrl.wait_subs_clean(t, e2SubsId, 10)
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqTwoRetriesNoRespSubDelRespInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |       RESTNotif |              |
+//     |       unsuccess |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |            [SUBS DELETE]       |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqRetryNoRespSubDelRespInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubReqTwoRetriesNoRespSubDelRespInSubmgr start")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubReReqToE2, 1},
+               Counter{cSubReqTimerExpiry, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 1st REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 2nd REST subscriber request for subscriber : %v", restSubId)
+
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+       // e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)     - TODO:  Should we delete this?
+       xappConn1.WaitRESTNotification(t, restSubId)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, delreq.RequestId.InstanceId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+func TestREST2eTermNotRespondingToSubReq(t *testing.T) {
+       CaseBegin("TestREST2eTermNotRespondingToSubReq start")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubReReqToE2, 1},
+               Counter{cSubReqTimerExpiry, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelReqTimerExpiry, 2},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 1st REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 2nd REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsDelReq(t)
+       xapp.Logger.Info("Ignore 1st INTERNAL delete request for subscriber : %v", restSubId)
+
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.RecvSubsDelReq(t)
+       xapp.Logger.Info("Ignore 2nd INTERNAL delete request for subscriber : %v", restSubId)
+
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqTwoRetriesNoRespSubDelRespInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |       RESTNotif |              |
+//     |       unsuccess |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |            [SUBS DELETE]       |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqTwoRetriesNoRespAtAllInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubReqTwoRetriesNoRespAtAllInSubmgr start")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubReReqToE2, 1},
+               Counter{cSubReqTimerExpiry, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelReReqToE2, 1},
+               Counter{cSubDelReqTimerExpiry, 2},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 1st REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+       xapp.Logger.Info("Ignore 2nd REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsDelReq(t)
+       xapp.Logger.Info("Ignore 1st INTERNAL delete request for subscriber : %v", restSubId)
+
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.RecvSubsDelReq(t)
+       xapp.Logger.Info("Ignore 2nd INTERNAL delete request for subscriber : %v", restSubId)
+
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqSubFailRespInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubFail |
+//     |                 |<-------------|
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |       RESTNotif |              |
+//     |       unsuccess |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |            [SUBS DELETE]       |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqSubFailRespInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubReqSubFailRespInSubmgr")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubFailFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+       fparams1 := &teststube2ap.E2StubSubsFailParams{}
+       fparams1.Set(crereq1)
+       e2termConn1.SendSubsFail(t, fparams1, cremsg1)
+
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", e2SubsId)
+
+       // REST subscription sill there to be deleted
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubDelReqRetryInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     |            [SUBS CREATE]       |
+//     |                 |              |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubDelReqRetryInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubDelReqRetryInSubmgr")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelReReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+       // Req
+       var params *teststube2ap.RESTSubsReqParams = nil
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       // E2t: Receive 1st SubsDelReq
+       e2termConn1.RecvSubsDelReq(t)
+
+       // E2t: Receive 2nd SubsDelReq and send SubsDelResp
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubDelReqTwoRetriesNoRespInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     |            [SUBS CREATE]       |
+//     |                 |              |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubDelReqTwoRetriesNoRespInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubDelReTwoRetriesNoRespInSubmgr")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelReReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       var params *teststube2ap.RESTSubsReqParams = nil
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       // E2t: Receive 1st SubsDelReq
+       e2termConn1.RecvSubsDelReq(t)
+
+       // E2t: Receive 2nd SubsDelReq and send SubsDelResp
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubDelReqSubDelFailRespInSubmgr
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     |            [SUBS CREATE]       |
+//     |                 |              |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelFail |
+//     |                 |<-------------|
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubDelReqSubDelFailRespInSubmgr(t *testing.T) {
+       CaseBegin("TestRESTSubDelReqSubDelFailRespInSubmgr")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelFailFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       var params *teststube2ap.RESTSubsReqParams = nil
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       // E2t: Send receive SubsDelReq and send SubsDelFail
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelFail(t, delreq, delmsg)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelOkSameAction
+//
+//   stub                             stub
+// +-------+     +-------+        +---------+    +---------+
+// | xapp2 |     | xapp1 |        | submgr  |    | e2term  |
+// +-------+     +-------+        +---------+    +---------+
+//     |             |                 |              |
+//     |             | RESTSubReq1     |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             |    RESTSubResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     |             |                 | SubReq1      |
+//     |             |                 |------------->|
+//     |             |                 |    SubResp1  |
+//     |             |                 |<-------------|
+//     |             |      RESTNotif1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     | RESTSubReq2                   |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |                  RESTSubResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             |      RESTNotif2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             | RESTSubDelReq1  |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             | RESTSubDelResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     | RESTSubDelReq2                |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             |                 | SubDelReq2   |
+//     |             |                 |------------->|
+//     |             |                 |              |
+//     |             |                 |  SubDelResp2 |
+//     |             |                 |<-------------|
+//     |             |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelOkSameAction(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkSameAction")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cMergedSubscriptions, 1},
+               Counter{cUnmergedSubscriptions, 1},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       // Req1
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       //Subs Create
+       restSubId1, e2SubsId1 := createSubscription(t, xappConn1, e2termConn1, params)
+       queryXappSubscription(t, int64(e2SubsId1), "RAN_NAME_1", []string{"localhost:13560"})
+
+       // Req2
+       params = xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetMeid("RAN_NAME_1")
+
+       xapp.Subscription.SetResponseCB(xappConn2.SubscriptionRespHandler)
+       xappConn2.WaitRESTNotificationForAnySubscriptionId(t)
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriberId : %v", restSubId2)
+       e2SubsId2 := <-xappConn2.RESTNotification
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId2)
+
+       queryXappSubscription(t, int64(e2SubsId1), "RAN_NAME_1", []string{"localhost:13560", "localhost:13660"})
+
+       // Del1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+
+       // Del2
+       deleteXapp2Subscription(t, &restSubId2)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestSubReqAndSubDelOkSameActionParallel
+//
+//   stub          stub                          stub
+// +-------+     +-------+     +---------+    +---------+
+// | xapp2 |     | xapp1 |     | submgr  |    | e2term  |
+// +-------+     +-------+     +---------+    +---------+
+//     |             |              |              |
+//     |             |              |              |
+//     |             |              |              |
+//     |             | SubReq1      |              |
+//     |             |------------->|              |
+//     |             |              |              |
+//     |             |              | SubReq1      |
+//     |             |              |------------->|
+//     |          SubReq2           |              |
+//     |--------------------------->|              |
+//     |             |              |    SubResp1  |
+//     |             |              |<-------------|
+//     |             |    SubResp1  |              |
+//     |             |<-------------|              |
+//     |             |              | SubReq2      |
+//     |             |              |------------->|
+//     |             |              |              |
+//     |             |              |    SubResp2  |
+//     |             |              |<-------------|
+//     |          SubResp2          |              |
+//     |<---------------------------|              |
+//     |             |              |              |
+//     |             | SubDelReq 1  |              |
+//     |             |------------->|              |
+//     |             |              |              |
+//     |             | SubDelResp 1 |              |
+//     |             |<-------------|              |
+//     |             |              |              |
+//     |         SubDelReq 2        |              |
+//     |--------------------------->|              |
+//     |             |              |              |
+//     |             |              | SubDelReq 2  |
+//     |             |              |------------->|
+//     |             |              |              |
+//     |             |              | SubDelReq 2  |
+//     |             |              |------------->|
+//     |             |              |              |
+//     |         SubDelResp 2       |              |
+//     |<---------------------------|              |
+//
+func TestRESTSubReqAndSubDelOkSameActionParallel(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkSameActionParallel")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params)
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+
+       params2 := xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params2)
+
+       xappConn1.ExpectRESTNotification(t, restSubId1)
+       e2termConn1.SendSubsResp(t, crereq1, cremsg1)
+       e2SubsId1 := xappConn1.WaitRESTNotification(t, restSubId1)
+
+       xappConn2.ExpectRESTNotification(t, restSubId2)
+       crereq2, cremsg2 := e2termConn1.RecvSubsReq(t)
+       e2termConn1.SendSubsResp(t, crereq2, cremsg2)
+       e2SubsId2 := xappConn2.WaitRESTNotification(t, restSubId2)
+
+       // Del1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+       mainCtrl.wait_subs_clean(t, e2SubsId1, 10)
+
+       // Del2
+       xappConn2.SendRESTSubsDelReq(t, &restSubId2)
+       delreq2, delmsg2 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq2, delmsg2)
+
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelNoAnswerSameActionParallel
+//
+//   stub          stub                             stub
+// +-------+     +-------+        +---------+    +---------+
+// | xapp2 |     | xapp1 |        | submgr  |    | e2term  |
+// +-------+     +-------+        +---------+    +---------+
+//     |             |                 |              |
+//     |             |                 |              |
+//     |             |                 |              |
+//     |             | RESTSubReq1     |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             |    RESTSubResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 | SubReq1      |
+//     |             |                 |------------->|
+//     | RESTSubReq2                   |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 | SubReq1      |
+//     |             |                 |------------->|
+//     |             |                 |              |
+//     |             |                 |              |
+//     |             |                 | SubDelReq    |
+//     |             |                 |------------->|
+//     |             |                 |              |
+//     |             |                 |   SubDelResp |
+//     |             |                 |<-------------|
+//     |             |      RESTNotif1 |              |
+//     |             |       unsuccess |              |
+//     |             |<----------------|              |
+//     |                    RESTNotif2 |              |
+//     |             |       unsuccess |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             | RESTSubDelReq1  |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             | RESTSubDelResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     | RESTSubDelReq2                |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelNoAnswerSameActionParallel(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelNoAnswerSameActionParallel")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // Req1
+       params1 := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params1)
+       crereq1, _ := e2termConn1.RecvSubsReq(t)
+
+       // Req2
+       subepcnt2 := mainCtrl.get_subs_entrypoint_cnt(t, crereq1.RequestId.InstanceId)
+       params2 := xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params2.SetMeid("RAN_NAME_1")
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params2)
+       mainCtrl.wait_subs_entrypoint_cnt_change(t, crereq1.RequestId.InstanceId, subepcnt2, 10)
+
+       //Req1 (retransmitted)
+       e2termConn1.RecvSubsReq(t)
+
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId1) // or restSubId2?
+       //      xappConn2.WaitRESTNotification(t)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+
+       e2SubsId1 := xappConn1.WaitRESTNotification(t, restSubId1)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", e2SubsId1)
+
+       //      e2SubsId2 := <-xappConn2.RESTNotification
+       //      xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", e2SubsId2)
+
+       // Del1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+
+       // Del2
+       xappConn2.SendRESTSubsDelReq(t, &restSubId2)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId1, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelNokSameActionParallel
+//
+//   stub          stub                             stub
+// +-------+     +-------+        +---------+    +---------+
+// | xapp2 |     | xapp1 |        | submgr  |    | e2term  |
+// +-------+     +-------+        +---------+    +---------+
+//     |             |                 |              |
+//     |             |                 |              |
+//     |             |                 |              |
+//     |             | RESTSubReq1     |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             |    RESTSubResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 | SubReq1      |
+//     |             |                 |------------->|
+//     | RESTSubReq2                   |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 |    SubFail1  |
+//     |             |                 |<-------------|
+//     |             |                 |              |
+//     |             |      RESTNotif1 |              |
+//     |             |       unsuccess |              |
+//     |             |<----------------|              |
+//     |                    RESTNotif2 |              |
+//     |             |       unsuccess |              |
+//     |<------------------------------|              |
+//     |             |                 | SubDelReq    |
+//     |             |                 |------------->|
+//     |             |                 |   SubDelResp |
+//     |             |                 |<-------------|
+//     |             |                 |              |
+//     |             | RESTSubDelReq1  |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             | RESTSubDelResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     | RESTSubDelReq2                |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelNokSameActionParallel(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelNokSameActionParallel")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubFailFromE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // Req1
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params)
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+
+       // Req2
+       subepcnt2 := mainCtrl.get_subs_entrypoint_cnt(t, crereq1.RequestId.InstanceId)
+       params2 := xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params2.SetMeid("RAN_NAME_1")
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params2)
+       mainCtrl.wait_subs_entrypoint_cnt_change(t, crereq1.RequestId.InstanceId, subepcnt2, 10)
+
+       // E2t: send SubsFail (first)
+       fparams1 := &teststube2ap.E2StubSubsFailParams{}
+       fparams1.Set(crereq1)
+       e2termConn1.SendSubsFail(t, fparams1, cremsg1)
+
+       // E2t: internal delete
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       xappConn1.WaitListedRestNotifications(t, []string{restSubId1, restSubId2})
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       e2SubsIdA := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 1.st XAPP notification received e2SubsId=%v", e2SubsIdA)
+       e2SubsIdB := <-xappConn1.ListedRESTNotifications
+       xapp.Logger.Info("TEST: 2.nd XAPP notification received e2SubsId=%v", e2SubsIdB)
+
+       // Del1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+
+       // Del2
+       xappConn2.SendRESTSubsDelReq(t, &restSubId2)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsIdA.E2SubsId, 10)
+       waitSubsCleanup(t, e2SubsIdB.E2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+func TestRESTSubReqPolicyAndSubDelOk(t *testing.T) {
+       CaseBegin("TestRESTSubReqPolicyAndSubDelOk")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST Policy subscriber request for subscriberId : %v", restSubId)
+
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsResp(t, crereq1, cremsg1)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId)
+
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqPolicyChangeAndSubDelOk
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |       RESTNotif |              |
+//     |<----------------|              |
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |       RESTNotif |              |
+//     |<----------------|              |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqPolicyChangeAndSubDelOk(t *testing.T) {
+       CaseBegin("TestRESTSubReqPolicyAndSubDelOk")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const policyParamCount int = 1
+
+       // Req
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Policy change
+       instanceId := int64(e2SubsId)
+       // GetRESTSubsReqPolicyParams sets some coutners on tc side.
+       params = xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       params.SubsReqParams.SubscriptionDetails[0].InstanceID = &instanceId
+       params.SetTimeToWait("w200ms")
+       restSubId, e2SubsId = createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelOkTwoE2termParallel
+//
+//   stub                             stub           stub
+// +-------+        +---------+    +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term1 |    | e2term2 |
+// +-------+        +---------+    +---------+    +---------+
+//     |                 |              |              |
+//     |                 |              |              |
+//     |                 |              |              |
+//     | RESTSubReq1     |              |              |
+//     |---------------->|              |              |
+//     |                 |              |              |
+//     |    RESTSubResp1 |              |              |
+//     |<----------------|              |              |
+//     |                 | SubReq1      |              |
+//     |                 |------------->|              |
+//     |                 |              |              |
+//     | RESTSubReq2     |              |              |
+//     |---------------->|              |              |
+//     |                 |              |              |
+//     |    RESTSubResp2 |              |              |
+//     |<----------------|              |              |
+//     |                 | SubReq2      |              |
+//     |                 |---------------------------->|
+//     |                 |              |              |
+//     |                 |    SubResp1  |              |
+//     |                 |<-------------|              |
+//     |      RESTNotif1 |              |              |
+//     |<----------------|              |              |
+//     |                 |    SubResp2  |              |
+//     |                 |<----------------------------|
+//     |      RESTNotif2 |              |              |
+//     |<----------------|              |              |
+//     |                 |              |              |
+//     |           [SUBS 1 DELETE]      |              |
+//     |                 |              |              |
+//     |           [SUBS 2 DELETE]      |              |
+//     |                 |              |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelOkTwoE2termParallel(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkTwoE2termParallel")
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // Req1
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId1 := xappConn1.SendRESTSubsReq(t, params)
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+
+       // Req2
+       params = xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetMeid("RAN_NAME_11")
+       // Here we use xappConn2 to simulate sending second request from same xapp as doing it from xappConn1
+       // would not work as notification would not be received
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+       crereq2, cremsg2 := e2termConn2.RecvSubsReq(t)
+
+       // Resp1
+       xappConn1.ExpectRESTNotification(t, restSubId1)
+       e2termConn1.SendSubsResp(t, crereq1, cremsg1)
+       e2SubsId1 := xappConn1.WaitRESTNotification(t, restSubId1)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId1=%v", e2SubsId1)
+
+       // Resp2
+       xappConn2.ExpectRESTNotification(t, restSubId2)
+       e2termConn2.SendSubsResp(t, crereq2, cremsg2)
+       e2SubsId2 := xappConn2.WaitRESTNotification(t, restSubId2)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId2=%v", e2SubsId2)
+
+       // Delete1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+
+       // Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, e2SubsId1, 10)
+
+       // Delete2
+       xappConn1.SendRESTSubsDelReq(t, &restSubId2)
+       delreq2, delmsg2 := e2termConn2.RecvSubsDelReq(t)
+       e2termConn2.SendSubsDelResp(t, delreq2, delmsg2)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAsn1EncodeFail
+//
+// In this case submgr send RICSubscriptionDeleteRequest after encode failure which should not happen!
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |  RESTSubDelResp |              |
+//     |     unsuccess   |              |
+//     |<----------------|              |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAsn1EncodeFail(t *testing.T) {
+       CaseBegin("TestRESTSubReqAsn1EncodeFail")
+
+       xapp.Logger.Info("Xapp-frame, v0.8.1 sufficient REST API validation")
+
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqInsertAndSubDelOk
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RestSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     | RESTNotif       |              |
+//     |<----------------|              |
+//     |       ...       |     ...      |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |   RESTSubDelResp|              |
+//     |<----------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqInsertAndSubDelOk(t *testing.T) {
+       CaseBegin("TestRESTInsertSubReqAndSubDelOk")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet int = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetSubActionTypes("insert")
+
+       // Req
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       // Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqNokAndSubDelOkWithRestartInMiddle
+//
+//   stub                          stub
+// +-------+     +---------+    +---------+
+// | xapp  |     | submgr  |    | e2term  |
+// +-------+     +---------+    +---------+
+//     |              |              |
+//     | RESTSubReq   |              |
+//     |------------->|              |
+//     |              |              |
+//     |              | SubReq       |
+//     |              |------------->|
+//     |              |              |
+//     |              |      SubResp |
+//     |                        <----|
+//     |                             |
+//     |        Submgr restart       |
+//     |                             |
+//     |              |              |
+//     |              | SubDelReq    |
+//     |              |------------->|
+//     |              |              |
+//     |              |   SubDelResp |
+//     |              |<-------------|
+//     |              |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqNokAndSubDelOkWithRestartInMiddle(t *testing.T) {
+       CaseBegin("TestRESTSubReqNokAndSubDelOkWithRestartInMiddle")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+       })
+
+       const subReqCount int = 1
+       const parameterSet = 1
+       const actionDefinitionPresent bool = true
+       const actionParamCount int = 1
+
+       // Remove possible existing subscription
+       mainCtrl.removeExistingSubscriptions(t)
+
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+
+       //Req
+       mainCtrl.SetResetTestFlag(t, true) // subs.DoNotWaitSubResp will be set TRUE for the subscription
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       e2termConn1.RecvSubsReq(t)
+
+       mainCtrl.SetResetTestFlag(t, false)
+
+       mainCtrl.SimulateRestart(t)
+       xapp.Logger.Debug("mainCtrl.SimulateRestart done")
+
+       //Del
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+
+       xappConn1.TestMsgChanEmpty(t)
+       xappConn2.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelOkWithRestartInMiddle
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |       RESTNotif |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |                                |
+//     |           Submgr restart       |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |  RESTSubDelResp |              |
+//     |<----------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelOkWithRestartInMiddle(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkWithRestartInMiddle")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 1},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Remove possible existing subscription
+       mainCtrl.removeExistingSubscriptions(t)
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       // Create subscription
+       restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber : %v", restSubId)
+
+       // Check subscription
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       // When SDL support for the REST Interface is added
+       // the submgr restart statement below should be removed
+       // from the comment.
+
+       //      mainCtrl.SimulateRestart(t)
+       //      xapp.Logger.Debug("mainCtrl.SimulateRestart done")
+
+       // Check subscription
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       // Delete subscription
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTSubReqAndSubDelOkSameActionWithRestartsInMiddle
+//
+//   stub                             stub
+// +-------+     +-------+        +---------+    +---------+
+// | xapp2 |     | xapp1 |        | submgr  |    | e2term  |
+// +-------+     +-------+        +---------+    +---------+
+//     |             |                 |              |
+//     |             | RESTSubReq1     |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             |    RESTSubResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     |             |                 | SubReq1      |
+//     |             |                 |------------->|
+//     |             |                 |    SubResp1  |
+//     |             |                 |<-------------|
+//     |             |      RESTNotif1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     | RESTSubReq2                   |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |                  RESTSubResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             |      RESTNotif2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             |           Submgr restart       |
+//     |             |                 |              |
+//     |             | RESTSubDelReq1  |              |
+//     |             |---------------->|              |
+//     |             |                 |              |
+//     |             | RESTSubDelResp1 |              |
+//     |             |<----------------|              |
+//     |             |                 |              |
+//     |             |           Submgr restart       |
+//     |             |                 |              |
+//     | RESTSubDelReq2                |              |
+//     |------------------------------>|              |
+//     |             |                 |              |
+//     |               RESTSubDelResp2 |              |
+//     |<------------------------------|              |
+//     |             |                 |              |
+//     |             |                 | SubDelReq2   |
+//     |             |                 |------------->|
+//     |             |                 |              |
+//     |             |                 |  SubDelResp2 |
+//     |             |                 |<-------------|
+//     |             |                 |              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTSubReqAndSubDelOkSameActionWithRestartsInMiddle(t *testing.T) {
+       CaseBegin("TestRESTSubReqAndSubDelOkSameActionWithRestartsInMiddle")
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 2},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cSubRespToXapp, 2},
+               Counter{cMergedSubscriptions, 1},
+               Counter{cUnmergedSubscriptions, 1},
+               Counter{cSubDelReqFromXapp, 2},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cSubDelRespToXapp, 2},
+       })
+
+       // Remove possible existing subscription
+       mainCtrl.removeExistingSubscriptions(t)
+
+       var params *teststube2ap.RESTSubsReqParams = nil
+
+       // Create subscription 1
+       restSubId1, e2SubsId1 := createSubscription(t, xappConn1, e2termConn1, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriber 1 : %v", restSubId1)
+
+       // Create subscription 2 with same action
+       params = xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       params.SetMeid("RAN_NAME_1")
+       xapp.Subscription.SetResponseCB(xappConn2.SubscriptionRespHandler)
+       xappConn2.WaitRESTNotificationForAnySubscriptionId(t)
+       restSubId2 := xappConn2.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriberId : %v", restSubId2)
+       e2SubsId2 := <-xappConn2.RESTNotification
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId2)
+
+       queryXappSubscription(t, int64(e2SubsId1), "RAN_NAME_1", []string{"localhost:13560", "localhost:13660"})
+
+       // When SDL support for the REST Interface is added
+       // the submgr restart statement below should be removed
+       // from the comment.
+
+       //      mainCtrl.SimulateRestart(t)
+       //      xapp.Logger.Debug("mainCtrl.SimulateRestart done")
+
+       // Delete subscription 1
+       xappConn1.SendRESTSubsDelReq(t, &restSubId1)
+
+       // When SDL support for the REST Interface is added
+       // the submgr restart statement below should be removed
+       // from the comment.
+
+       //      mainCtrl.SimulateRestart(t)
+       //      xapp.Logger.Debug("mainCtrl.SimulateRestart done")
+
+       queryXappSubscription(t, int64(e2SubsId1), "RAN_NAME_1", []string{"localhost:13660"})
+
+       // Delete subscription 2
+       deleteXapp2Subscription(t, &restSubId2)
+
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId2, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+
+//-----------------------------------------------------------------------------
+// TestRESTReportSubReqAndSubDelOk
+//
+//   stub                             stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RestSubReq      |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |     RESTSubResp |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     | RESTNotif       |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |      SubResp |
+//     |                 |<-------------|
+//     | RESTNotif       |              |
+//     |<----------------|              |
+//     |       ...       |     ...      |
+//     |                 |              |
+//     |                 |              |
+//     | RESTSubDelReq   |              |
+//     |---------------->|              |
+//     |                 |              |
+//     |                 | SubDelReq    |
+//     |                 |------------->|
+//     |                 |              |
+//     |                 |   SubDelResp |
+//     |                 |<-------------|
+//     |                 |              |
+//     |   RESTSubDelResp|              |
+//     |<----------------|              |
+//
+//-----------------------------------------------------------------------------
+func TestRESTReportSubReqAndSubDelOk(t *testing.T) {
+       CaseBegin("TestRESTReportSubReqAndSubDelOk")
+       subReqCount := 1
+       parameterSet := 1 // E2SM-gNB-X2
+       actionDefinitionPresent := true
+       actionParamCount := 1
+       testIndex := 1
+       RESTReportSubReqAndSubDelOk(t, subReqCount, parameterSet, actionDefinitionPresent, actionParamCount, testIndex)
+}
+
+func RESTReportSubReqAndSubDelOk(t *testing.T, subReqCount int, parameterSet int, actionDefinitionPresent bool, actionParamCount int, testIndex int) {
+       xapp.Logger.Info("TEST: TestRESTReportSubReqAndSubDelOk with parameter set %v", testIndex)
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       var e2SubsId []uint32
+       for i := 0; i < subReqCount; i++ {
+               crereq, cremsg := e2termConn1.RecvSubsReq(t)
+               xappConn1.ExpectRESTNotification(t, restSubId)
+
+               e2termConn1.SendSubsResp(t, crereq, cremsg)
+               instanceId := xappConn1.WaitRESTNotification(t, restSubId)
+               xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", instanceId)
+               e2SubsId = append(e2SubsId, instanceId)
+               resp, _ := xapp.Subscription.QuerySubscriptions()
+               assert.Equal(t, resp[i].SubscriptionID, (int64)(instanceId))
+               assert.Equal(t, resp[i].Meid, "RAN_NAME_1")
+               assert.Equal(t, resp[i].ClientEndpoint, []string{"localhost:13560"})
+
+       }
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       for i := 0; i < subReqCount; i++ {
+               delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+               e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+       }
+
+       // Wait that subs is cleaned
+       for i := 0; i < subReqCount; i++ {
+               mainCtrl.wait_subs_clean(t, e2SubsId[i], 10)
+       }
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+}
+
+/*
+func TestRESTPolicySubReqAndSubDelOk(t *testing.T) {
+       CaseBegin("TestRESTPolicySubReqAndSubDelOk")
+
+       subReqCount := 2
+       actionDefinitionPresent := true
+       policyParamCount := 1
+       testIndex := 1
+       RESTPolicySubReqAndSubDelOk(t, subReqCount, actionDefinitionPresent, policyParamCount, testIndex)
+
+       subReqCount = 19
+       actionDefinitionPresent = false
+       policyParamCount = 0
+       testIndex = 2
+       RESTPolicySubReqAndSubDelOk(t, subReqCount, actionDefinitionPresent, policyParamCount, testIndex)
+}
+*/
+func RESTPolicySubReqAndSubDelOk(t *testing.T, subReqCount int, actionDefinitionPresent bool, policyParamCount int, testIndex int) {
+       xapp.Logger.Info("TEST: TestRESTPolicySubReqAndSubDelOk with parameter set %v", testIndex)
+
+       // Req
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       //params := xappConn1.GetRESTSubsReqPolicyParams1(subReqCount, actionDefinitionPresent, policyParamCount)
+       //restSubId := xappConn1.SendRESTPolicySubsReq(t, params)
+
+       var e2SubsId []uint32
+       for i := 0; i < subReqCount; i++ {
+               crereq, cremsg := e2termConn1.RecvSubsReq(t)
+               xappConn1.ExpectRESTNotification(t, restSubId)
+               e2termConn1.SendSubsResp(t, crereq, cremsg)
+               instanceId := xappConn1.WaitRESTNotification(t, restSubId)
+               xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", instanceId)
+               e2SubsId = append(e2SubsId, instanceId)
+       }
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+
+       for i := 0; i < subReqCount; i++ {
+               delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+               e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+       }
+
+       // Wait that subs is cleaned
+       for i := 0; i < subReqCount; i++ {
+               mainCtrl.wait_subs_clean(t, e2SubsId[i], 10)
+       }
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+}
+
+/*
+func TestRESTTwoPolicySubReqAndSubDelOk(t *testing.T) {
+
+       subReqCount := 2
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 2},
+               Counter{cSubRespFromE2, 2},
+               Counter{cSubRespToXapp, 2},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 2},
+               Counter{cSubDelRespFromE2, 2},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       e2SubsIds := sendAndReceiveMultipleE2SubReqs(t, subReqCount, xappConn1, e2termConn1, restSubId)
+
+       assert.Equal(t, len(e2SubsIds), 2)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       sendAndReceiveMultipleE2DelReqs(t, e2SubsIds, e2termConn1)
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+/*
+func TestRESTPolicySubReqAndSubDelOkFullAmount(t *testing.T) {
+
+       subReqCount := 19
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, 19},
+               Counter{cSubRespFromE2, 19},
+               Counter{cSubRespToXapp, 19},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 19},
+               Counter{cSubDelRespFromE2, 19},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       e2SubsIds := sendAndReceiveMultipleE2SubReqs(t, subReqCount, xappConn1, e2termConn1, restSubId)
+
+       assert.Equal(t, len(e2SubsIds), 19)
+
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       sendAndReceiveMultipleE2DelReqs(t, e2SubsIds, e2termConn1)
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+/*
+func TestRESTTwoReportSubReqAndSubDelOk(t *testing.T) {
+
+       subReqCount := 2
+       parameterSet := 1
+       actionDefinitionPresent := true
+       actionParamCount := 1
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, uint64(subReqCount)},
+               Counter{cSubRespFromE2, uint64(subReqCount)},
+               Counter{cSubRespToXapp, uint64(subReqCount)},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, uint64(subReqCount)},
+               Counter{cSubDelRespFromE2, uint64(subReqCount)},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       e2SubsIds := sendAndReceiveMultipleE2SubReqs(t, subReqCount, xappConn1, e2termConn1, restSubId)
+
+       assert.Equal(t, len(e2SubsIds), subReqCount)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       sendAndReceiveMultipleE2DelReqs(t, e2SubsIds, e2termConn1)
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+/*
+func TestRESTTwoReportSubReqAndSubDelOkNoActParams(t *testing.T) {
+
+       subReqCount := 2
+       parameterSet := 1
+       actionDefinitionPresent := false
+       actionParamCount := 0
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, uint64(subReqCount)},
+               Counter{cSubRespFromE2, uint64(subReqCount)},
+               Counter{cSubRespToXapp, uint64(subReqCount)},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, uint64(subReqCount)},
+               Counter{cSubDelRespFromE2, uint64(subReqCount)},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       e2SubsIds := sendAndReceiveMultipleE2SubReqs(t, subReqCount, xappConn1, e2termConn1, restSubId)
+
+       assert.Equal(t, len(e2SubsIds), subReqCount)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       sendAndReceiveMultipleE2DelReqs(t, e2SubsIds, e2termConn1)
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+/*
+func TestRESTFullAmountReportSubReqAndSubDelOk(t *testing.T) {
+
+       subReqCount := 19
+       parameterSet := 1
+       actionDefinitionPresent := false
+       actionParamCount := 0
+
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cSubReqFromXapp, 1},
+               Counter{cSubReqToE2, uint64(subReqCount)},
+               Counter{cSubRespFromE2, uint64(subReqCount)},
+               Counter{cSubRespToXapp, uint64(subReqCount)},
+               Counter{cSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, uint64(subReqCount)},
+               Counter{cSubDelRespFromE2, uint64(subReqCount)},
+               Counter{cSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       e2SubsIds := sendAndReceiveMultipleE2SubReqs(t, subReqCount, xappConn1, e2termConn1, restSubId)
+
+       assert.Equal(t, len(e2SubsIds), subReqCount)
+
+       // Del
+       xappConn1.SendRESTSubsDelReq(t, &restSubId)
+       sendAndReceiveMultipleE2DelReqs(t, e2SubsIds, e2termConn1)
+
+       xappConn1.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+}
+*/
+////////////////////////////////////////////////////////////////////////////////////
+//   Services for UT cases
+////////////////////////////////////////////////////////////////////////////////////
+const subReqCount int = 1
+const parameterSet = 1
+const actionDefinitionPresent bool = true
+const actionParamCount int = 1
+const policyParamCount int = 1
+const host string = "localhost"
+
+func createSubscription(t *testing.T, fromXappConn *teststube2ap.E2Stub, toE2termConn *teststube2ap.E2Stub, params *teststube2ap.RESTSubsReqParams) (string, uint32) {
+       if params == nil {
+               params = fromXappConn.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       }
+       restSubId := fromXappConn.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST subscriber request for subscriberId : %v", restSubId)
+
+       crereq1, cremsg1 := toE2termConn.RecvSubsReq(t)
+       fromXappConn.ExpectRESTNotification(t, restSubId)
+       toE2termConn.SendSubsResp(t, crereq1, cremsg1)
+       e2SubsId := fromXappConn.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId)
+
+       return restSubId, e2SubsId
+}
+
+func createXapp2MergedSubscription(t *testing.T, meid string) (string, uint32) {
+
+       params := xappConn2.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       if meid != "" {
+               params.SetMeid(meid)
+       }
+       xapp.Subscription.SetResponseCB(xappConn2.SubscriptionRespHandler)
+       restSubId := xappConn2.SendRESTSubsReq(t, params)
+       xappConn2.ExpectRESTNotification(t, restSubId)
+       xapp.Logger.Info("Send REST subscriber request for subscriberId : %v", restSubId)
+       e2SubsId := xappConn2.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId)
+
+       return restSubId, e2SubsId
+}
+
+func createXapp1PolicySubscription(t *testing.T) (string, uint32) {
+       params := xappConn1.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       xapp.Logger.Info("Send REST Policy subscriber request for subscriberId : %v", restSubId)
+
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsResp(t, crereq1, cremsg1)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("REST notification received e2SubsId=%v", e2SubsId)
+
+       return restSubId, e2SubsId
+}
+
+func createXapp1ReportSubscriptionE2Fail(t *testing.T) (string, uint32) {
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount, parameterSet, actionDefinitionPresent, actionParamCount)
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+
+       crereq1, cremsg1 := e2termConn1.RecvSubsReq(t)
+       fparams1 := &teststube2ap.E2StubSubsFailParams{}
+       fparams1.Set(crereq1)
+       e2termConn1.SendSubsFail(t, fparams1, cremsg1)
+
+       delreq1, delmsg1 := e2termConn1.RecvSubsDelReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+       e2termConn1.SendSubsDelResp(t, delreq1, delmsg1)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+       xapp.Logger.Info("TEST: REST notification received e2SubsId=%v", e2SubsId)
+
+       return restSubId, e2SubsId
+}
+
+func deleteSubscription(t *testing.T, fromXappConn *teststube2ap.E2Stub, toE2termConn *teststube2ap.E2Stub, restSubId *string) {
+       fromXappConn.SendRESTSubsDelReq(t, restSubId)
+       delreq, delmsg := toE2termConn.RecvSubsDelReq(t)
+       toE2termConn.SendSubsDelResp(t, delreq, delmsg)
+}
+
+func deleteXapp1Subscription(t *testing.T, restSubId *string) {
+       xappConn1.SendRESTSubsDelReq(t, restSubId)
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+}
+
+func deleteXapp2Subscription(t *testing.T, restSubId *string) {
+       xappConn2.SendRESTSubsDelReq(t, restSubId)
+       delreq, delmsg := e2termConn1.RecvSubsDelReq(t)
+       e2termConn1.SendSubsDelResp(t, delreq, delmsg)
+}
+
+func queryXappSubscription(t *testing.T, e2SubsId int64, meid string, endpoint []string) {
+       resp, _ := xapp.Subscription.QuerySubscriptions()
+       assert.Equal(t, resp[0].SubscriptionID, e2SubsId)
+       assert.Equal(t, resp[0].Meid, meid)
+       assert.Equal(t, resp[0].ClientEndpoint, endpoint)
+}
+
+func waitSubsCleanup(t *testing.T, e2SubsId uint32, timeout int) {
+       //Wait that subs is cleaned
+       mainCtrl.wait_subs_clean(t, e2SubsId, timeout)
+
+       xappConn1.TestMsgChanEmpty(t)
+       xappConn2.TestMsgChanEmpty(t)
+       e2termConn1.TestMsgChanEmpty(t)
+       mainCtrl.wait_registry_empty(t, timeout)
+}
+
+func sendAndReceiveMultipleE2SubReqs(t *testing.T, count int, fromXappConn *teststube2ap.E2Stub, toE2termConn *teststube2ap.E2Stub, restSubId string) []uint32 {
+
+       var e2SubsId []uint32
+
+       for i := 0; i < count; i++ {
+               xapp.Logger.Info("TEST: %d ===================================== BEGIN CRE ============================================", i+1)
+               crereq, cremsg := toE2termConn.RecvSubsReq(t)
+               fromXappConn.ExpectRESTNotification(t, restSubId)
+               toE2termConn.SendSubsResp(t, crereq, cremsg)
+               instanceId := fromXappConn.WaitRESTNotification(t, restSubId)
+               e2SubsId = append(e2SubsId, instanceId)
+               xapp.Logger.Info("TEST: %v", e2SubsId)
+               xapp.Logger.Info("TEST: %d ===================================== END CRE ============================================", i+1)
+               <-time.After(100 * time.Millisecond)
+       }
+       return e2SubsId
+}
+
+func sendAndReceiveMultipleE2DelReqs(t *testing.T, e2SubsIds []uint32, toE2termConn *teststube2ap.E2Stub) {
+
+       for i := 0; i < len(e2SubsIds); i++ {
+               xapp.Logger.Info("TEST: %d ===================================== BEGIN DEL ============================================", i+1)
+               delreq, delmsg := toE2termConn.RecvSubsDelReq(t)
+               toE2termConn.SendSubsDelResp(t, delreq, delmsg)
+               <-time.After(1 * time.Second)
+               xapp.Logger.Info("TEST: %d ===================================== END DEL ============================================", i+1)
+               <-time.After(100 * time.Millisecond)
+       }
+
+       // Wait that subs is cleaned
+       for i := 0; i < len(e2SubsIds); i++ {
+               mainCtrl.wait_subs_clean(t, e2SubsIds[i], 10)
+       }
+
+}
index 97bedfa..cc09efd 100644 (file)
@@ -21,12 +21,13 @@ package control
 
 import (
        "encoding/json"
-       "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_models"
-       "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
        "net/http"
        "sync"
        "testing"
        "time"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_models"
+       "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
 )
 
 //-----------------------------------------------------------------------------
@@ -37,6 +38,7 @@ type HttpEventWaiter struct {
        teststub.TestWrapper
        resultChan   chan bool
        nextActionOk bool
+       sleep        int
 }
 
 func (msg *HttpEventWaiter) SetResult(res bool) {
@@ -81,10 +83,22 @@ func (tc *testingHttpRtmgrStub) AllocNextEvent(nextAction bool) *HttpEventWaiter
        return eventWaiter
 }
 
+func (tc *testingHttpRtmgrStub) AllocNextSleep(sleep int, nextAction bool) *HttpEventWaiter {
+       eventWaiter := &HttpEventWaiter{
+               resultChan:   make(chan bool),
+               nextActionOk: nextAction,
+               sleep:        sleep,
+       }
+       eventWaiter.TestWrapper.Init("localhost:" + tc.port)
+       tc.NextEvent(eventWaiter)
+       return eventWaiter
+}
+
 func (tc *testingHttpRtmgrStub) http_handler(w http.ResponseWriter, r *http.Request) {
 
        tc.Lock()
        defer tc.Unlock()
+       var id int32 = -1
 
        if r.Method == http.MethodPost || r.Method == http.MethodDelete {
                var req rtmgr_models.XappSubscriptionData
@@ -93,6 +107,7 @@ func (tc *testingHttpRtmgrStub) http_handler(w http.ResponseWriter, r *http.Requ
                        tc.Error("%s", err.Error())
                }
                tc.Info("handling SubscriptionID=%d Address=%s Port=%d", *req.SubscriptionID, *req.Address, *req.Port)
+               id = *req.SubscriptionID
        }
        if r.Method == http.MethodPut {
                var req rtmgr_models.XappList
@@ -111,6 +126,10 @@ func (tc *testingHttpRtmgrStub) http_handler(w http.ResponseWriter, r *http.Requ
                        if tc.eventWaiter.nextActionOk == false {
                                code = 400
                        }
+                       if tc.eventWaiter.sleep != 0 {
+                               <-time.After(time.Duration(tc.eventWaiter.sleep) * time.Millisecond)
+                               tc.Info("sleeping done, %v", id)
+                       }
                }
        case http.MethodDelete:
                code = 200
index e7ddbc0..5072cf4 100644 (file)
 package control
 
 import (
+       "os"
+       "testing"
+       "time"
+
        "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
        "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststubdummy"
        "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststube2ap"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "os"
-       "testing"
-       "time"
 )
 
 //-----------------------------------------------------------------------------
@@ -187,13 +188,13 @@ func ut_test_init() func() {
        //
        //---------------------------------
        tent.Info("### xapp1 stub run ###")
-       xappConn1 = teststube2ap.CreateNewE2Stub("xappstub1", xapp1src, teststub.RmrRtgSvc{}, "RMRXAPP1STUB", teststubPortSeed)
+       xappConn1 = teststube2ap.CreateNewE2Stub("xappstub1", xapp1src, teststub.RmrRtgSvc{}, "RMRXAPP1STUB", teststubPortSeed, "RAN_NAME_1", "localhost", 13560, 8080)
 
        //---------------------------------
        //
        //---------------------------------
        tent.Info("### xapp2 stub run ###")
-       xappConn2 = teststube2ap.CreateNewE2Stub("xappstub2", xapp2src, teststub.RmrRtgSvc{}, "RMRXAPP2STUB", teststubPortSeed)
+       xappConn2 = teststube2ap.CreateNewE2Stub("xappstub2", xapp2src, teststub.RmrRtgSvc{}, "RMRXAPP2STUB", teststubPortSeed, "RAN_NAME_2", "localhost", 13660, 8080)
 
        //---------------------------------
        //
index d830aa7..b8d2350 100644 (file)
 package teststube2ap
 
 import (
+       "fmt"
+       "strconv"
+       "testing"
+       "time"
+
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap_wrapper"
        "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
+       clientmodel "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientmodel"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "strconv"
-       "testing"
 )
 
 //-----------------------------------------------------------------------------
@@ -41,6 +45,11 @@ type RmrTransactionId struct {
        meid *xapp.RMRMeid
 }
 
+type E2RestIds struct {
+       RestSubsId string
+       E2SubsId   uint32
+}
+
 func (trans *RmrTransactionId) String() string {
        meidstr := "N/A"
        if trans.meid != nil {
@@ -51,17 +60,36 @@ func (trans *RmrTransactionId) String() string {
 
 type E2Stub struct {
        teststub.RmrStubControl
-       xid_seq uint64
+       xid_seq                     uint64
+       subscriptionId              string
+       requestCount                int
+       CallBackNotification        chan int64
+       RESTNotification            chan uint32
+       CallBackListedNotifications chan E2RestIds
+       ListedRESTNotifications     chan E2RestIds
+       clientEndpoint              clientmodel.SubscriptionParamsClientEndpoint
+       meid                        string
+       restSubsIdList              []string
 }
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func CreateNewE2Stub(desc string, srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc, stat string, mtypeseed int) *E2Stub {
+func CreateNewE2Stub(desc string, srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc, stat string, mtypeseed int, ranName string, host string, RMRPort int64, HTTPPort int64) *E2Stub {
        tc := &E2Stub{}
        tc.RmrStubControl.Init(desc, srcId, rtgSvc, stat, mtypeseed)
        tc.xid_seq = 1
        tc.SetCheckXid(true)
+       tc.CallBackNotification = make(chan int64)
+       tc.RESTNotification = make(chan uint32)
+       tc.CallBackListedNotifications = make(chan E2RestIds)
+       tc.ListedRESTNotifications = make(chan E2RestIds, 2)
+       var endPoint clientmodel.SubscriptionParamsClientEndpoint
+       endPoint.Host = host
+       endPoint.HTTPPort = &HTTPPort
+       endPoint.RMRPort = &RMRPort
+       tc.clientEndpoint = endPoint
+       tc.meid = ranName
        return tc
 }
 
@@ -593,3 +621,384 @@ func (tc *E2Stub) SendSubsDelFail(t *testing.T, req *e2ap.E2APSubscriptionDelete
                tc.TestError(t, "RMR SEND FAILED: %s", snderr.Error())
        }
 }
+
+// REST code below all
+
+/*****************************************************************************/
+// REST interface specific functions are below
+
+//-----------------------------------------------------------------------------
+// Callback handler for subscription response notifications
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) SubscriptionRespHandler(resp *clientmodel.SubscriptionResponse) {
+       if tc.subscriptionId == *resp.SubscriptionID {
+               tc.Info("REST notification received SubscriptionID=%s, InstanceID=%v, RequestorID=%v (%v)",
+                       *resp.SubscriptionID, *resp.SubscriptionInstances[0].InstanceID, *resp.SubscriptionInstances[0].RequestorID, tc)
+               tc.CallBackNotification <- *resp.SubscriptionInstances[0].InstanceID
+       } else {
+               tc.Info("MISMATCHING REST notification received SubscriptionID=%s<>%s, InstanceID=%v, RequestorID=%v (%v)",
+                       tc.subscriptionId, *resp.SubscriptionID, *resp.SubscriptionInstances[0].InstanceID, *resp.SubscriptionInstances[0].RequestorID, tc)
+       }
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) ExpectRESTNotification(t *testing.T, restSubsId string) {
+
+       tc.Info("### Started to wait REST notification for %v on port %v f(RMR port %v), %v responses expected", restSubsId, *tc.clientEndpoint.HTTPPort, *tc.clientEndpoint.RMRPort, tc.requestCount)
+       tc.restSubsIdList = []string{restSubsId}
+       xapp.Subscription.SetResponseCB(tc.ListedRestNotifHandler)
+       if tc.requestCount == 0 {
+               tc.TestError(t, "### NO REST notifications SET received for endpoint=%s, request zount ZERO! (%v)", tc.clientEndpoint, tc)
+       }
+       go func() {
+               select {
+               case e2Ids := <-tc.CallBackListedNotifications:
+                       if tc.requestCount == 0 {
+                               tc.TestError(t, "### REST notification count unexpectedly ZERO for %s (%v)", restSubsId, tc)
+                       } else if e2Ids.RestSubsId != restSubsId {
+                               tc.TestError(t, "### Unexpected REST notifications received |%s:%s| (%v)", e2Ids.RestSubsId, restSubsId, tc)
+                       } else {
+                               tc.requestCount--
+                               if tc.requestCount == 0 {
+                                       tc.Info("### All expected REST notifications received for %s (%v)", e2Ids.RestSubsId, tc)
+                               } else {
+                                       tc.Info("### Expected REST notifications received for %s, (%v)", e2Ids.RestSubsId, tc)
+                               }
+                               tc.Info("### REST Notification received Notif for %s : %v", e2Ids.RestSubsId, e2Ids.E2SubsId)
+                               tc.ListedRESTNotifications <- e2Ids
+                       }
+               case <-time.After(15 * time.Second):
+                       err := fmt.Errorf("### Timeout 15s expired while expecting REST notification for subsId: %v", restSubsId)
+                       tc.TestError(t, "%s", err.Error())
+               }
+       }()
+}
+
+func (tc *E2Stub) WaitRESTNotification(t *testing.T, restSubsId string) uint32 {
+       select {
+       case e2SubsId := <-tc.ListedRESTNotifications:
+               if e2SubsId.RestSubsId == restSubsId {
+                       tc.Info("### Expected REST notifications received %s, e2SubsId %v for endpoint=%s, (%v)", e2SubsId.RestSubsId, e2SubsId.E2SubsId, tc.clientEndpoint, tc)
+                       return e2SubsId.E2SubsId
+               } else {
+                       tc.TestError(t, "### Unexpected REST notifications received %s, expected %s for endpoint=%s, (%v)", e2SubsId.RestSubsId, restSubsId, tc.clientEndpoint, tc)
+                       return 0
+               }
+       case <-time.After(15 * time.Second):
+               err := fmt.Errorf("### Timeout 15s expired while waiting REST notification for subsId: %v", restSubsId)
+               tc.TestError(t, "%s", err.Error())
+               panic("WaitRESTNotification - timeout error")
+       }
+       return 0
+}
+
+func (tc *E2Stub) WaitRESTNotificationForAnySubscriptionId(t *testing.T) {
+       go func() {
+               tc.Info("### REST notifications received for endpoint=%s, (%v)", tc.clientEndpoint, tc)
+               select {
+               case e2SubsId := <-tc.CallBackNotification:
+                       tc.Info("### REST notifications received e2SubsId %v for endpoint=%s, (%v)", e2SubsId, tc.clientEndpoint, tc)
+                       tc.RESTNotification <- (uint32)(e2SubsId)
+               case <-time.After(15 * time.Second):
+                       err := fmt.Errorf("### Timeout 15s expired while waiting REST notification")
+                       tc.TestError(t, "%s", err.Error())
+                       tc.RESTNotification <- 0
+               }
+       }()
+}
+
+func (tc *E2Stub) ListedRestNotifHandler(resp *clientmodel.SubscriptionResponse) {
+
+       if len(tc.restSubsIdList) == 0 {
+               tc.Error("Unexpected listed REST notifications received for endpoint=%s, expected restSubsId list size was ZERO!", tc.clientEndpoint)
+       } else {
+               for i, subsId := range tc.restSubsIdList {
+                       if *resp.SubscriptionID == subsId {
+                               //tc.Info("Listed REST notifications received SubscriptionID=%s, InstanceID=%v, RequestorID=%v",
+                               //      *resp.SubscriptionID, *resp.SubscriptionInstances[0].InstanceID, *resp.SubscriptionInstances[0].RequestorID)
+
+                               tc.restSubsIdList = append(tc.restSubsIdList[:i], tc.restSubsIdList[i+1:]...)
+                               //tc.Info("Removed %s from Listed REST notifications, %v entries left", *resp.SubscriptionID, len(tc.restSubsIdList))
+
+                               tc.CallBackListedNotifications <- E2RestIds{*resp.SubscriptionID, uint32(*resp.SubscriptionInstances[0].InstanceID)}
+
+                               if len(tc.restSubsIdList) == 0 {
+                                       //tc.Info("All listed REST notifications received for endpoint=%s", tc.clientEndpoint)
+                               }
+
+                               return
+                       }
+               }
+               tc.Error("UNKONWN REST notification received SubscriptionID=%s<>%s, InstanceID=%v, RequestorID=%v (%v)",
+                       tc.subscriptionId, *resp.SubscriptionID, *resp.SubscriptionInstances[0].InstanceID, *resp.SubscriptionInstances[0].RequestorID, tc)
+       }
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) WaitListedRestNotifications(t *testing.T, restSubsIds []string) {
+       tc.Info("Started to wait REST notifications %v on port %v f(RMR port %v)", restSubsIds, *tc.clientEndpoint.HTTPPort, *tc.clientEndpoint.RMRPort)
+
+       tc.restSubsIdList = restSubsIds
+       xapp.Subscription.SetResponseCB(tc.ListedRestNotifHandler)
+
+       for i := 0; i < len(restSubsIds); i++ {
+               go func() {
+                       select {
+                       case e2Ids := <-tc.CallBackListedNotifications:
+                               tc.Info("Listed Notification waiter received Notif for %s : %v", e2Ids.RestSubsId, e2Ids.E2SubsId)
+                               tc.ListedRESTNotifications <- e2Ids
+                       case <-time.After(15 * time.Second):
+                               err := fmt.Errorf("Timeout 15s expired while waiting Listed REST notification")
+                               tc.TestError(t, "%s", err.Error())
+                               tc.RESTNotification <- 0
+                       }
+               }()
+       }
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) SendRESTSubsReq(t *testing.T, params *RESTSubsReqParams) string { // This need to be edited according to new specification
+       tc.Info("Posting REST Report subscriptions to Submgr")
+
+       if params == nil {
+               tc.Info("SendRESTReportSubsReq: params == nil")
+               return ""
+       }
+
+       resp, err := xapp.Subscription.Subscribe(&params.SubsReqParams)
+       if err != nil {
+               // Swagger generated code makes checks for the values that are inserted the subscription function
+               // If error cause is unknown and POST is not done, the problem is in the inserted values
+               tc.Error("REST report subscriptions failed %s", err.Error())
+       }
+       tc.subscriptionId = *resp.SubscriptionID
+       tc.Info("REST report subscriptions pushed successfully. SubscriptionID = %s, RequestCount = %v", *resp.SubscriptionID, tc.requestCount)
+       return *resp.SubscriptionID
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) GetRESTSubsReqReportParams(subReqCount int, parameterSet int, actionDefinitionPresent bool, actionParamCount int) *RESTSubsReqParams {
+
+       reportParams := RESTSubsReqParams{}
+       if parameterSet == 1 {
+               reportParams.GetRESTSubsReqReportParams1(subReqCount, actionDefinitionPresent, actionParamCount, &tc.clientEndpoint, &tc.meid)
+       } else if parameterSet == 2 {
+
+       } else {
+               tc.Error("Invalid parameterSet=%v", parameterSet)
+       }
+       tc.requestCount = subReqCount
+       return &reportParams
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) GetRESTSubsReqReportParams1(subReqCount int, actionDefinitionPresent bool, actionParamCount int) *RESTSubsReqParams {
+
+       reportParams := RESTSubsReqParams{}
+       reportParams.GetRESTSubsReqReportParams1(subReqCount, actionDefinitionPresent, actionParamCount, &tc.clientEndpoint, &tc.meid)
+       tc.requestCount = subReqCount
+       return &reportParams
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+type RESTSubsReqParams struct {
+       SubsReqParams clientmodel.SubscriptionParams
+}
+
+func (p *RESTSubsReqParams) GetRESTSubsReqReportParams1(subReqCount int, actionDefinitionPresent bool, actionParamCount int, clientEndpoint *clientmodel.SubscriptionParamsClientEndpoint, meid *string) {
+
+       // E2SM-gNB-X2
+       p.SubsReqParams.ClientEndpoint = clientEndpoint
+       p.SubsReqParams.Meid = meid
+       var rANFunctionID int64 = 33
+       p.SubsReqParams.RANFunctionID = &rANFunctionID
+
+       //      reqId := int64(1)
+       //seqId := int64(1)
+       actionId := int64(1)
+       actionType := "report"
+       subsequestActioType := "continue"
+       timeToWait := "w10ms"
+
+       for requestCount := 0; requestCount < subReqCount; requestCount++ {
+               reqId := int64(requestCount) + 1
+               seqId := int64(requestCount) + 1
+               subscriptionDetail := &clientmodel.SubscriptionDetail{
+                       RequestorID: &reqId,
+                       InstanceID:  &seqId,
+                       EventTriggers: &clientmodel.EventTriggerDefinition{
+                               OctetString: "1234" + strconv.Itoa(requestCount),
+                       },
+                       ActionToBeSetupList: clientmodel.ActionsToBeSetup{
+                               &clientmodel.ActionToBeSetup{
+                                       ActionID:   &actionId,
+                                       ActionType: &actionType,
+                                       ActionDefinition: &clientmodel.ActionDefinition{
+                                               OctetString: "5678" + strconv.Itoa(requestCount),
+                                       },
+                                       SubsequentAction: &clientmodel.SubsequentAction{
+                                               SubsequentActionType: &subsequestActioType,
+                                               TimeToWait:           &timeToWait,
+                                       },
+                               },
+                       },
+               }
+               p.SubsReqParams.SubscriptionDetails = append(p.SubsReqParams.SubscriptionDetails, subscriptionDetail)
+       }
+
+}
+
+func (p *RESTSubsReqParams) SetMeid(MEID string) {
+       p.SubsReqParams.Meid = &MEID
+}
+
+func (p *RESTSubsReqParams) SetEndpoint(HTTP_port int64, RMR_port int64, host string) {
+       var endpoint clientmodel.SubscriptionParamsClientEndpoint
+       endpoint.HTTPPort = &HTTP_port
+       endpoint.RMRPort = &RMR_port
+       endpoint.Host = host
+       p.SubsReqParams.ClientEndpoint = &endpoint
+}
+
+func (p *RESTSubsReqParams) SetEndpointHost(host string) {
+
+       if p.SubsReqParams.ClientEndpoint.Host != "" {
+               if p.SubsReqParams.ClientEndpoint.Host != host {
+                       // Renaming toto, print something tc.Info("Posting REST subscription request to Submgr")
+                       err := fmt.Errorf("hostname change attempt: %s -> %s", p.SubsReqParams.ClientEndpoint.Host, host)
+                       panic(err)
+               }
+       }
+       p.SubsReqParams.ClientEndpoint.Host = host
+}
+
+func (p *RESTSubsReqParams) SetHTTPEndpoint(HTTP_port int64, host string) {
+
+       p.SubsReqParams.ClientEndpoint.HTTPPort = &HTTP_port
+
+       p.SetEndpointHost(host)
+
+       if p.SubsReqParams.ClientEndpoint.RMRPort == nil {
+               var RMR_port int64
+               p.SubsReqParams.ClientEndpoint.RMRPort = &RMR_port
+       }
+}
+
+func (p *RESTSubsReqParams) SetSubActionTypes(actionType string) {
+
+       for _, subDetail := range p.SubsReqParams.SubscriptionDetails {
+               for _, action := range subDetail.ActionToBeSetupList {
+                       if action != nil {
+                               action.ActionType = &actionType
+                       }
+               }
+       }
+}
+
+func (p *RESTSubsReqParams) SetRMREndpoint(RMR_port int64, host string) {
+
+       p.SubsReqParams.ClientEndpoint.RMRPort = &RMR_port
+
+       p.SetEndpointHost(host)
+
+       if p.SubsReqParams.ClientEndpoint.HTTPPort == nil {
+               var HTTP_port int64
+               p.SubsReqParams.ClientEndpoint.HTTPPort = &HTTP_port
+       }
+}
+
+func (p *RESTSubsReqParams) SetTimeToWait(timeToWait string) {
+
+       for _, subDetail := range p.SubsReqParams.SubscriptionDetails {
+               for _, action := range subDetail.ActionToBeSetupList {
+                       if action != nil && action.SubsequentAction != nil {
+                               action.SubsequentAction.TimeToWait = &timeToWait
+                       }
+               }
+       }
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) SendRESTSubsDelReq(t *testing.T, subscriptionID *string) {
+
+       if *subscriptionID == "" {
+               tc.Error("REST error in deleting subscriptions. Empty SubscriptionID = %s", *subscriptionID)
+       }
+       tc.Info("REST deleting E2 subscriptions. SubscriptionID = %s", *subscriptionID)
+
+       err := xapp.Subscription.Unsubscribe(*subscriptionID)
+       if err != nil {
+               tc.Error("REST Delete subscription failed %s", err.Error())
+       }
+       tc.Info("REST delete subscription pushed to submgr successfully. SubscriptionID = %s", *subscriptionID)
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) GetRESTSubsReqPolicyParams(subReqCount int, actionDefinitionPresent bool, policyParamCount int) *RESTSubsReqParams {
+
+       policyParams := RESTSubsReqParams{}
+       policyParams.GetRESTSubsReqPolicyParams(subReqCount, actionDefinitionPresent, policyParamCount, &tc.clientEndpoint, &tc.meid)
+       tc.requestCount = subReqCount
+       return &policyParams
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (p *RESTSubsReqParams) GetRESTSubsReqPolicyParams(subReqCount int, actionDefinitionPresent bool, policyParamCount int, clientEndpoint *clientmodel.SubscriptionParamsClientEndpoint, meid *string) {
+
+       p.SubsReqParams.ClientEndpoint = clientEndpoint
+       p.SubsReqParams.Meid = meid
+       var rANFunctionID int64 = 33
+       p.SubsReqParams.RANFunctionID = &rANFunctionID
+
+       //      reqId := int64(1)
+       //seqId := int64(1)
+       actionId := int64(1)
+       actionType := "policy"
+       subsequestActioType := "continue"
+       timeToWait := "w10ms"
+
+       for requestCount := 0; requestCount < subReqCount; requestCount++ {
+               reqId := int64(requestCount) + 1
+               seqId := int64(0)
+               subscriptionDetail := &clientmodel.SubscriptionDetail{
+                       RequestorID: &reqId,
+                       InstanceID:  &seqId,
+                       EventTriggers: &clientmodel.EventTriggerDefinition{
+                               OctetString: "1234" + strconv.Itoa(requestCount),
+                       },
+                       ActionToBeSetupList: clientmodel.ActionsToBeSetup{
+                               &clientmodel.ActionToBeSetup{
+                                       ActionID:   &actionId,
+                                       ActionType: &actionType,
+                                       ActionDefinition: &clientmodel.ActionDefinition{
+                                               OctetString: "5678" + strconv.Itoa(requestCount),
+                                       },
+                                       SubsequentAction: &clientmodel.SubsequentAction{
+                                               SubsequentActionType: &subsequestActioType,
+                                               TimeToWait:           &timeToWait,
+                                       },
+                               },
+                       },
+               }
+               p.SubsReqParams.SubscriptionDetails = append(p.SubsReqParams.SubscriptionDetails, subscriptionDetail)
+       }
+
+}