From afbf95f5756a7b781859beb1e68b41f7319ed208 Mon Sep 17 00:00:00 2001 From: archagge Date: Wed, 14 Apr 2021 08:54:05 +0300 Subject: [PATCH] Xapp-frame, v0.8.1 Rest Subscription Creation /Query /Deletion 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 --- e2ap/pkg/e2ap/msg_e2ap.go | 32 + e2ap/pkg/e2ap/msg_e2ap_subscription.go | 7 + go.mod | 1 + go.sum | 2 + pkg/control/client.go | 7 +- pkg/control/control.go | 263 +++- pkg/control/e2ap.go | 45 + pkg/control/registry.go | 73 +- pkg/control/restendpoint.go | 57 + pkg/control/transaction.go | 5 +- pkg/control/ut_messaging_test.go | 2490 +++++++++++++++++++++++++++++++- pkg/control/ut_stub_rtmgr_test.go | 23 +- pkg/control/ut_test.go | 11 +- pkg/teststube2ap/stubE2.go | 417 +++++- 14 files changed, 3390 insertions(+), 43 deletions(-) create mode 100644 pkg/control/restendpoint.go diff --git a/e2ap/pkg/e2ap/msg_e2ap.go b/e2ap/pkg/e2ap/msg_e2ap.go index f4ca81a..1e3ea70 100644 --- a/e2ap/pkg/e2ap/msg_e2ap.go +++ b/e2ap/pkg/e2ap/msg_e2ap.go @@ -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 diff --git a/e2ap/pkg/e2ap/msg_e2ap_subscription.go b/e2ap/pkg/e2ap/msg_e2ap_subscription.go index 8c6910e..6be0b6e 100644 --- a/e2ap/pkg/e2ap/msg_e2ap_subscription.go +++ b/e2ap/pkg/e2ap/msg_e2ap_subscription.go @@ -19,6 +19,13 @@ package e2ap +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +type SubscriptionRequestList struct { + E2APSubscriptionRequests []E2APSubscriptionRequest +} + //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- diff --git a/go.mod b/go.mod index 2ea2cc8..76d405e 100644 --- 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 --- 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= diff --git a/pkg/control/client.go b/pkg/control/client.go index 11367ed..b62044e 100644 --- a/pkg/control/client.go +++ b/pkg/control/client.go @@ -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" ) //----------------------------------------------------------------------------- diff --git a/pkg/control/control.go b/pkg/control/control.go index 02110b6..aee1158 100755 --- a/pkg/control/control.go +++ b/pkg/control/control.go @@ -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") diff --git a/pkg/control/e2ap.go b/pkg/control/e2ap.go index b21eb3f..c547567 100644 --- a/pkg/control/e2ap.go +++ b/pkg/control/e2ap.go @@ -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 +} + //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- diff --git a/pkg/control/registry.go b/pkg/control/registry.go index 1c6ab3d..d7f8011 100644 --- a/pkg/control/registry.go +++ b/pkg/control/registry.go @@ -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 index 0000000..b872c47 --- /dev/null +++ b/pkg/control/restendpoint.go @@ -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 +} diff --git a/pkg/control/transaction.go b/pkg/control/transaction.go index 570cb7a..efb630c 100644 --- a/pkg/control/transaction.go +++ b/pkg/control/transaction.go @@ -20,11 +20,12 @@ 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" ) //----------------------------------------------------------------------------- diff --git a/pkg/control/ut_messaging_test.go b/pkg/control/ut_messaging_test.go index 81464b8..71bc92d 100644 --- a/pkg/control/ut_messaging_test.go +++ b/pkg/control/ut_messaging_test.go @@ -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) + } + +} diff --git a/pkg/control/ut_stub_rtmgr_test.go b/pkg/control/ut_stub_rtmgr_test.go index 97bedfa..cc09efd 100644 --- a/pkg/control/ut_stub_rtmgr_test.go +++ b/pkg/control/ut_stub_rtmgr_test.go @@ -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 diff --git a/pkg/control/ut_test.go b/pkg/control/ut_test.go index e7ddbc0..5072cf4 100644 --- a/pkg/control/ut_test.go +++ b/pkg/control/ut_test.go @@ -20,13 +20,14 @@ 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) //--------------------------------- // diff --git a/pkg/teststube2ap/stubE2.go b/pkg/teststube2ap/stubE2.go index d830aa7..b8d2350 100644 --- a/pkg/teststube2ap/stubE2.go +++ b/pkg/teststube2ap/stubE2.go @@ -20,12 +20,16 @@ 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(¶ms.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) + } + +} -- 2.16.6