RICPLT-3015 Reusing subscription if same EventTrigger and Action
Change-Id: Ibda45d0864ce1626fb3973519a799a69579e7614
Signed-off-by: Juha Hyttinen <juha.hyttinen@nokia.com>
diff --git a/pkg/control/client.go b/pkg/control/client.go
index 4146428..73e2ee0 100644
--- a/pkg/control/client.go
+++ b/pkg/control/client.go
@@ -66,9 +66,9 @@
deleteHandle.WithXappSubscriptionData(&deleteData)
_, _, err = rc.rtClient.Handle.DeleteXappSubscriptionHandle(deleteHandle)
case UPDATE:
- updateData := rtmgr_models.XappList{}
+ var updateData rtmgr_models.XappList
for i := range subRouteAction.EpList.Endpoints {
- updateData[i] = &rtmgr_models.XappElement{Address: &subRouteAction.EpList.Endpoints[i].Addr, Port: &subRouteAction.EpList.Endpoints[i].Port}
+ updateData = append(updateData, &rtmgr_models.XappElement{Address: &subRouteAction.EpList.Endpoints[i].Addr, Port: &subRouteAction.EpList.Endpoints[i].Port})
}
updateHandle := rtmgrhandle.NewUpdateXappSubscriptionHandleParamsWithTimeout(10 * time.Second)
updateHandle.WithSubscriptionID(subRouteAction.SubID)
diff --git a/pkg/control/control.go b/pkg/control/control.go
index c2b33b7..dee7e65 100755
--- a/pkg/control/control.go
+++ b/pkg/control/control.go
@@ -216,12 +216,6 @@
return
}
- if subs.IsTransactionReserved() {
- err := fmt.Errorf("Currently parallel or queued transactions are not allowed")
- xapp.Logger.Error("XAPP-SubReq: %s", idstring(trans, subs, err))
- return
- }
-
//
// Wake subs request
//
@@ -275,12 +269,6 @@
return
}
- if subs.IsTransactionReserved() {
- err := fmt.Errorf("Currently parallel or queued transactions are not allowed")
- xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(trans, subs, err))
- return
- }
-
//
// Wake subs delete
//
@@ -310,23 +298,47 @@
xapp.Logger.Debug("SUBS-SubReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String())
+ subs.mutex.Lock()
if subs.SubRespMsg != nil {
- xapp.Logger.Debug("SUBS-SubReq: Handling (immediate response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
+ xapp.Logger.Debug("SUBS-SubReq: Handling (immediate resp response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
parentTrans.SendEvent(subs.SubRespMsg, 0)
+ subs.mutex.Unlock()
return
}
+ if subs.SubFailMsg != nil {
+ xapp.Logger.Debug("SUBS-SubReq: Handling (immediate fail response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
+ parentTrans.SendEvent(subs.SubFailMsg, 0)
+ subs.mutex.Unlock()
+ go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
+ return
+ }
+ if subs.valid == false {
+ xapp.Logger.Debug("SUBS-SubReq: Handling (immediate nil response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
+ parentTrans.SendEvent(nil, 0)
+ subs.mutex.Unlock()
+ go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
+ return
+ }
+ subs.mutex.Unlock()
event := c.sendE2TSubscriptionRequest(subs, trans, parentTrans)
switch themsg := event.(type) {
case *e2ap.E2APSubscriptionResponse:
+ subs.mutex.Lock()
subs.SubRespMsg = themsg
+ subs.mutex.Unlock()
parentTrans.SendEvent(event, 0)
return
case *e2ap.E2APSubscriptionFailure:
- //TODO: Possible delete and one retry for subs req
+ subs.mutex.Lock()
+ subs.SubFailMsg = themsg
+ subs.mutex.Unlock()
parentTrans.SendEvent(event, 0)
default:
xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(trans, subs, nil))
+ subs.mutex.Lock()
+ subs.valid = false
+ subs.mutex.Unlock()
c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
parentTrans.SendEvent(nil, 0)
}
@@ -337,6 +349,7 @@
//-------------------------------------------------------------------
// SUBS DELETE Handling
//-------------------------------------------------------------------
+
func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *Transaction) {
trans := c.tracker.NewTransaction(subs.GetMeid())
@@ -346,9 +359,21 @@
xapp.Logger.Debug("SUBS-SubDelReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String())
- event := c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
+ subs.mutex.Lock()
+ if subs.valid && subs.EpList.HasEndpoint(parentTrans.GetEndpoint()) && subs.EpList.Size() == 1 {
+ subs.valid = false
+ subs.mutex.Unlock()
+ c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
+ } else {
+ subs.mutex.Unlock()
+ }
- parentTrans.SendEvent(event, 0)
+ subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
+ subDelRespMsg.RequestId.Id = subs.SubReqMsg.RequestId.Id
+ subDelRespMsg.RequestId.Seq = uint32(subs.GetSubId())
+ subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
+ parentTrans.SendEvent(subDelRespMsg, 0)
+
go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
}
diff --git a/pkg/control/registry.go b/pkg/control/registry.go
index 2750b78..6abdcdb 100644
--- a/pkg/control/registry.go
+++ b/pkg/control/registry.go
@@ -45,29 +45,74 @@
}
}
-func (r *Registry) AssignToSubscription(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, error) {
- r.mutex.Lock()
- defer r.mutex.Unlock()
-
- var sequenceNumber uint16
-
- //
- // Allocate subscription
- //
+func (r *Registry) allocateSubs(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, error) {
if len(r.subIds) > 0 {
- sequenceNumber = r.subIds[0]
+ sequenceNumber := r.subIds[0]
r.subIds = r.subIds[1:]
if _, ok := r.register[sequenceNumber]; ok == true {
r.subIds = append(r.subIds, sequenceNumber)
- return nil, fmt.Errorf("Registry: Failed to reserves subscription")
+ return nil, fmt.Errorf("Registry: Failed to reserve subscription exists")
}
- } else {
- return nil, fmt.Errorf("Registry: Failed to reserves subscription no free ids")
+ subs := &Subscription{
+ registry: r,
+ Seq: sequenceNumber,
+ Meid: trans.Meid,
+ SubReqMsg: subReqMsg,
+ valid: true,
+ }
+
+ if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
+ r.subIds = append(r.subIds, subs.Seq)
+ return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
+ }
+
+ return subs, nil
}
- subs := &Subscription{
- registry: r,
- Seq: sequenceNumber,
- Meid: trans.Meid,
+ return nil, fmt.Errorf("Registry: Failed to reserve subscription no free ids")
+}
+
+func (r *Registry) findExistingSubs(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) *Subscription {
+ for _, subs := range r.register {
+ if subs.IsSame(trans, subReqMsg) {
+
+ //
+ // check if there has been race conditions
+ //
+ subs.mutex.Lock()
+ //subs has been set to invalid
+ if subs.valid == false {
+ subs.mutex.Unlock()
+ continue
+ }
+ // try to add to endpointlist.
+ if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
+ subs.mutex.Unlock()
+ continue
+ }
+ subs.mutex.Unlock()
+
+ //Race collision during parallel incoming and deleted
+ xapp.Logger.Debug("Registry: Identical subs found %s for %s", subs.String(), trans.String())
+ return subs
+ }
+ }
+ return nil
+}
+
+func (r *Registry) AssignToSubscription(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, error) {
+ var err error
+ var newAlloc bool
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+
+ subs := r.findExistingSubs(trans, subReqMsg)
+
+ if subs == nil {
+ subs, err = r.allocateSubs(trans, subReqMsg)
+ if err != nil {
+ return nil, err
+ }
+ newAlloc = true
}
//
@@ -76,17 +121,12 @@
subs.mutex.Lock()
defer subs.mutex.Unlock()
- if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
- r.subIds = append(r.subIds, sequenceNumber)
- return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
- }
epamount := subs.EpList.Size()
r.mutex.Unlock()
//
// Subscription route updates
//
- var err error
if epamount == 1 {
subRouteAction := SubRouteInfo{CREATE, subs.EpList, subs.Seq}
err = r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
@@ -97,18 +137,23 @@
r.mutex.Lock()
if err != nil {
- r.subIds = append(r.subIds, sequenceNumber)
+ if newAlloc {
+ r.subIds = append(r.subIds, subs.Seq)
+ }
return nil, err
}
- subs.SubReqMsg = subReqMsg
- r.register[sequenceNumber] = subs
+ if newAlloc {
+ r.register[subs.Seq] = subs
+ }
xapp.Logger.Debug("Registry: Create %s", subs.String())
xapp.Logger.Debug("Registry: substable=%v", r.register)
return subs, nil
}
+// TODO: Needs better logic when there is concurrent calls
func (r *Registry) RemoveFromSubscription(subs *Subscription, trans *Transaction, waitRouteClean time.Duration) error {
+
r.mutex.Lock()
defer r.mutex.Unlock()
subs.mutex.Lock()
diff --git a/pkg/control/subscription.go b/pkg/control/subscription.go
index 45c13ec..5bfe2e1 100644
--- a/pkg/control/subscription.go
+++ b/pkg/control/subscription.go
@@ -31,6 +31,7 @@
//-----------------------------------------------------------------------------
type Subscription struct {
mutex sync.Mutex // Lock
+ valid bool // valid
registry *Registry // Registry
Seq uint16 // SubsId
Meid *xapp.RMRMeid // Meid/ RanName
@@ -39,6 +40,7 @@
TheTrans *Transaction // Ongoing transaction from xapp
SubReqMsg *e2ap.E2APSubscriptionRequest // Subscription information
SubRespMsg *e2ap.E2APSubscriptionResponse // Subscription information
+ SubFailMsg *e2ap.E2APSubscriptionFailure // Subscription information
}
func (s *Subscription) String() string {
@@ -91,3 +93,81 @@
s.mutex.Unlock()
s.TransLock.Unlock()
}
+
+func (s *Subscription) IsSame(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ if s.valid == false {
+ return false
+ }
+
+ if s.SubReqMsg == nil {
+ return false
+ }
+
+ if s.Meid.RanName != trans.Meid.RanName {
+ return false
+ }
+
+ if s.EpList.Size() == 0 {
+ return false
+ }
+
+ //Somehow special case ... ?
+ if s.EpList.HasEndpoint(trans.GetEndpoint()) == true {
+ return false
+ }
+
+ // EventTrigger check
+ if s.SubReqMsg.EventTriggerDefinition.InterfaceDirection != subReqMsg.EventTriggerDefinition.InterfaceDirection ||
+ s.SubReqMsg.EventTriggerDefinition.ProcedureCode != subReqMsg.EventTriggerDefinition.ProcedureCode ||
+ s.SubReqMsg.EventTriggerDefinition.TypeOfMessage != subReqMsg.EventTriggerDefinition.TypeOfMessage {
+ return false
+ }
+
+ if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[0] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[0] ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[1] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[1] ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[2] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[2] {
+ return false
+ }
+
+ if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[0] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[0] ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[1] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[1] ||
+ s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[2] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[2] {
+ return false
+ }
+
+ // Actions check
+ if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
+ return false
+ }
+
+ for _, acts := range s.SubReqMsg.ActionSetups {
+ for _, actt := range subReqMsg.ActionSetups {
+ if acts.ActionId != actt.ActionId {
+ return false
+ }
+ if acts.ActionType != actt.ActionType {
+ return false
+ }
+
+ if acts.ActionDefinition.Present != actt.ActionDefinition.Present ||
+ acts.ActionDefinition.StyleId != actt.ActionDefinition.StyleId ||
+ acts.ActionDefinition.ParamId != actt.ActionDefinition.ParamId {
+ return false
+ }
+ if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
+ acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
+ acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
+ return false
+ }
+ }
+ }
+
+ return true
+}
diff --git a/pkg/control/ut_ctrl_submgr_test.go b/pkg/control/ut_ctrl_submgr_test.go
index 197eb43..8403c93 100644
--- a/pkg/control/ut_ctrl_submgr_test.go
+++ b/pkg/control/ut_ctrl_submgr_test.go
@@ -43,6 +43,20 @@
return mainCtrl
}
+func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
+ cnt := int(0)
+ i := 1
+ for ; i <= secs*2; i++ {
+ cnt = len(mc.c.registry.register)
+ if cnt == 0 {
+ return true
+ }
+ time.Sleep(500 * time.Millisecond)
+ }
+ testError(t, "(general) no registry empty within %d secs: %d", secs, cnt)
+ return false
+}
+
func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId int, secs int) bool {
var subs *Subscription
i := 1
diff --git a/pkg/control/ut_messaging_test.go b/pkg/control/ut_messaging_test.go
index 3b43c3a..40207b3 100644
--- a/pkg/control/ut_messaging_test.go
+++ b/pkg/control/ut_messaging_test.go
@@ -52,7 +52,7 @@
waiter := rtmgrHttp.AllocNextEvent(false)
newSubsId := mainCtrl.get_subid(t)
- xappConn1.handle_xapp_subs_req(t, nil)
+ xappConn1.handle_xapp_subs_req(t, nil, nil)
waiter.WaitResult(t)
//Wait that subs is cleaned
@@ -61,6 +61,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -101,7 +102,7 @@
xapp.Logger.Info("TestSubReqAndSubDelOk")
waiter := rtmgrHttp.AllocNextEvent(true)
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
waiter.WaitResult(t)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
@@ -121,6 +122,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -155,11 +157,11 @@
xapp.Logger.Info("TestSubReqRetransmission")
//Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
seqBef := mainCtrl.get_msgcounter(t)
- xappConn1.handle_xapp_subs_req(t, cretrans) //Retransmitted SubReq
+ xappConn1.handle_xapp_subs_req(t, nil, cretrans) //Retransmitted SubReq
mainCtrl.wait_msgcounter_change(t, seqBef, 10)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
@@ -177,6 +179,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -212,7 +215,7 @@
xapp.Logger.Info("TestSubDelReqRetransmission")
//Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
e2SubsId := xappConn1.handle_xapp_subs_resp(t, cretrans)
@@ -234,6 +237,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -247,44 +251,53 @@
// | [SUBS CREATE] |
// | | |
// | | |
-// | SubDelReq | |
+// | SubDelReq 1 | |
// |------------->| |
// | | |
-// | | SubDelReq |
+// | | SubDelReq 1 |
// | |------------->|
// | | |
-// | SubDelReq | |
+// | SubDelReq 2 | |
// | (same sub) | |
// | (diff xid) | |
// |------------->| |
// | | |
-// | | SubDelResp |
+// | | SubDelResp 1 |
// | |<-------------|
// | | |
-// | SubDelResp | |
+// | SubDelResp 1 | |
+// |<-------------| |
+// | | |
+// | SubDelResp 2 | |
// |<-------------| |
//
//-----------------------------------------------------------------------------
+
func TestSubDelReqCollision(t *testing.T) {
xapp.Logger.Info("TestSubDelReqCollision")
//Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
e2SubsId := xappConn1.handle_xapp_subs_resp(t, cretrans)
//Subs Delete
- deltrans := xappConn1.handle_xapp_subs_del_req(t, nil, e2SubsId)
- delreq, delmsg := e2termConn.handle_e2term_subs_del_req(t)
+ xappConn1.handle_xapp_subs_del_req(t, nil, e2SubsId)
+ delreq1, delmsg1 := e2termConn.handle_e2term_subs_del_req(t)
+ // Subs Delete colliding
seqBef := mainCtrl.get_msgcounter(t)
- deltranscol := xappConn1.newXappTransaction(nil, "RAN_NAME_1")
- xappConn1.handle_xapp_subs_del_req(t, deltranscol, e2SubsId) //Colliding SubDelReq
+ deltranscol2 := xappConn1.newXappTransaction(nil, "RAN_NAME_1")
+ xappConn1.handle_xapp_subs_del_req(t, deltranscol2, e2SubsId) //Colliding SubDelReq
mainCtrl.wait_msgcounter_change(t, seqBef, 10)
- e2termConn.handle_e2term_subs_del_resp(t, delreq, delmsg)
- xappConn1.handle_xapp_subs_del_resp(t, deltrans)
+ // Del resp for first and second
+ e2termConn.handle_e2term_subs_del_resp(t, delreq1, delmsg1)
+
+ // don't care in which order responses are received
+ xappConn1.handle_xapp_subs_del_resp(t, nil)
+ xappConn1.handle_xapp_subs_del_resp(t, nil)
//Wait that subs is cleaned
mainCtrl.wait_subs_clean(t, e2SubsId, 10)
@@ -292,6 +305,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -336,11 +350,17 @@
xapp.Logger.Info("TestSubReqAndSubDelOkTwoParallel")
//Req1
- cretrans1 := xappConn1.handle_xapp_subs_req(t, nil)
+ rparams1 := &test_subs_req_params{}
+ rparams1.Init()
+ rparams1.req.EventTriggerDefinition.ProcedureCode = 5
+ cretrans1 := xappConn1.handle_xapp_subs_req(t, rparams1, nil)
crereq1, cremsg1 := e2termConn.handle_e2term_subs_req(t)
//Req2
- cretrans2 := xappConn2.handle_xapp_subs_req(t, nil)
+ rparams2 := &test_subs_req_params{}
+ rparams2.Init()
+ rparams2.req.EventTriggerDefinition.ProcedureCode = 28
+ cretrans2 := xappConn2.handle_xapp_subs_req(t, rparams2, nil)
crereq2, cremsg2 := e2termConn.handle_e2term_subs_req(t)
//Resp1
@@ -370,6 +390,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -418,14 +439,14 @@
//Req1
cretrans1 := xappConn1.newXappTransaction(nil, "RAN_NAME_1")
- xappConn1.handle_xapp_subs_req(t, cretrans1)
+ xappConn1.handle_xapp_subs_req(t, nil, cretrans1)
crereq1, cremsg1 := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq1, cremsg1)
e2SubsId1 := xappConn1.handle_xapp_subs_resp(t, cretrans1)
//Req2
cretrans2 := xappConn1.newXappTransaction(nil, "RAN_NAME_2")
- xappConn1.handle_xapp_subs_req(t, cretrans2)
+ xappConn1.handle_xapp_subs_req(t, nil, cretrans2)
crereq2, cremsg2 := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq2, cremsg2)
e2SubsId2 := xappConn1.handle_xapp_subs_resp(t, cretrans2)
@@ -451,6 +472,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -487,7 +509,7 @@
xapp.Logger.Info("TestSubReqRetryInSubmgr start")
// Xapp: Send SubsReq
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
// E2t: Receive 1st SubsReq
e2termConn.handle_e2term_subs_req(t)
@@ -510,6 +532,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -549,7 +572,7 @@
xapp.Logger.Info("TestSubReqTwoRetriesNoRespSubDelRespInSubmgr start")
// Xapp: Send SubsReq
- xappConn1.handle_xapp_subs_req(t, nil)
+ xappConn1.handle_xapp_subs_req(t, nil, nil)
// E2t: Receive 1st SubsReq
e2termConn.handle_e2term_subs_req(t)
@@ -567,6 +590,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -603,7 +627,7 @@
xapp.Logger.Info("TestSubReqTwoRetriesNoRespAtAllInSubmgr start")
// Xapp: Send SubsReq
- xappConn1.handle_xapp_subs_req(t, nil)
+ xappConn1.handle_xapp_subs_req(t, nil, nil)
// E2t: Receive 1st SubsReq
e2termConn.handle_e2term_subs_req(t)
@@ -623,6 +647,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -653,7 +678,7 @@
xapp.Logger.Info("TestSubReqSubFailRespInSubmgr start")
// Xapp: Send SubsReq
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
// E2t: Receive SubsReq and send SubsFail
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
@@ -670,6 +695,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -705,7 +731,7 @@
xapp.Logger.Info("TestSubDelReqRetryInSubmgr start")
// Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
e2SubsId := xappConn1.handle_xapp_subs_resp(t, cretrans)
@@ -730,6 +756,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -763,7 +790,7 @@
xapp.Logger.Info("TestSubDelReTwoRetriesNoRespInSubmgr start")
// Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
e2SubsId := xappConn1.handle_xapp_subs_resp(t, cretrans)
@@ -787,6 +814,7 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
}
//-----------------------------------------------------------------------------
@@ -820,7 +848,7 @@
xapp.Logger.Info("TestSubReqSubDelFailRespInSubmgr start")
// Subs Create
- cretrans := xappConn1.handle_xapp_subs_req(t, nil)
+ cretrans := xappConn1.handle_xapp_subs_req(t, nil, nil)
crereq, cremsg := e2termConn.handle_e2term_subs_req(t)
e2termConn.handle_e2term_subs_resp(t, crereq, cremsg)
e2SubsId := xappConn1.handle_xapp_subs_resp(t, cretrans)
@@ -841,4 +869,297 @@
xappConn1.TestMsgCnt(t)
xappConn2.TestMsgCnt(t)
e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
+}
+
+//-----------------------------------------------------------------------------
+// TestSubReqAndSubDelOkSameAction
+//
+// stub stub
+// +-------+ +---------+ +---------+
+// | xapp | | submgr | | e2term |
+// +-------+ +---------+ +---------+
+// | | |
+// | | |
+// | | |
+// | SubReq1 | |
+// |------------->| |
+// | | |
+// | | SubReq1 |
+// | |------------->|
+// | | SubResp1 |
+// | |<-------------|
+// | SubResp1 | |
+// |<-------------| |
+// | | |
+// | SubReq2 | |
+// |------------->| |
+// | | |
+// | SubResp2 | |
+// |<-------------| |
+// | | |
+// | SubDelReq 1 | |
+// |------------->| |
+// | | |
+// | SubDelResp 1 | |
+// |<-------------| |
+// | | |
+// | SubDelReq 2 | |
+// |------------->| |
+// | | |
+// | | SubDelReq 2 |
+// | |------------->|
+// | | |
+// | | SubDelReq 2 |
+// | |------------->|
+// | | |
+// | SubDelResp 2 | |
+// |<-------------| |
+//
+//-----------------------------------------------------------------------------
+func TestSubReqAndSubDelOkSameAction(t *testing.T) {
+ xapp.Logger.Info("TestSubReqAndSubDelOkSameAction")
+
+ //Req1
+ rparams1 := &test_subs_req_params{}
+ rparams1.Init()
+ cretrans1 := xappConn1.handle_xapp_subs_req(t, rparams1, nil)
+ crereq1, cremsg1 := e2termConn.handle_e2term_subs_req(t)
+ e2termConn.handle_e2term_subs_resp(t, crereq1, cremsg1)
+ e2SubsId1 := xappConn1.handle_xapp_subs_resp(t, cretrans1)
+
+ //Req2
+ rparams2 := &test_subs_req_params{}
+ rparams2.Init()
+ cretrans2 := xappConn2.handle_xapp_subs_req(t, rparams2, nil)
+ //crereq2, cremsg2 := e2termConn.handle_e2term_subs_req(t)
+ //e2termConn.handle_e2term_subs_resp(t, crereq2, cremsg2)
+ e2SubsId2 := xappConn2.handle_xapp_subs_resp(t, cretrans2)
+
+ //Del1
+ deltrans1 := xappConn1.handle_xapp_subs_del_req(t, nil, e2SubsId1)
+ //e2termConn.handle_e2term_subs_del_req(t)
+ //e2termConn.handle_e2term_subs_del_resp(t, delreq1, delmsg1)
+ xappConn1.handle_xapp_subs_del_resp(t, deltrans1)
+ //Wait that subs is cleaned
+ //mainCtrl.wait_subs_clean(t, e2SubsId1, 10)
+
+ //Del2
+ deltrans2 := xappConn2.handle_xapp_subs_del_req(t, nil, e2SubsId2)
+ delreq2, delmsg2 := e2termConn.handle_e2term_subs_del_req(t)
+ e2termConn.handle_e2term_subs_del_resp(t, delreq2, delmsg2)
+ xappConn2.handle_xapp_subs_del_resp(t, deltrans2)
+ //Wait that subs is cleaned
+ mainCtrl.wait_subs_clean(t, e2SubsId2, 10)
+
+ xappConn1.TestMsgCnt(t)
+ xappConn2.TestMsgCnt(t)
+ e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
+}
+
+//-----------------------------------------------------------------------------
+// TestSubReqAndSubDelOkSameActionParallel
+//
+// stub stub
+// +-------+ +---------+ +---------+
+// | xapp | | submgr | | e2term |
+// +-------+ +---------+ +---------+
+// | | |
+// | | |
+// | | |
+// | SubReq1 | |
+// |------------->| |
+// | | |
+// | | SubReq1 |
+// | |------------->|
+// | SubReq2 | |
+// |------------->| |
+// | | SubResp1 |
+// | |<-------------|
+// | SubResp1 | |
+// |<-------------| |
+// | | |
+// | SubResp2 | |
+// |<-------------| |
+// | | |
+// | SubDelReq 1 | |
+// |------------->| |
+// | | |
+// | SubDelResp 1 | |
+// |<-------------| |
+// | | |
+// | SubDelReq 2 | |
+// |------------->| |
+// | | |
+// | | SubDelReq 2 |
+// | |------------->|
+// | | |
+// | | SubDelReq 2 |
+// | |------------->|
+// | | |
+// | SubDelResp 2 | |
+// |<-------------| |
+//
+//-----------------------------------------------------------------------------
+func TestSubReqAndSubDelOkSameActionParallel(t *testing.T) {
+ xapp.Logger.Info("TestSubReqAndSubDelOkSameActionParallel")
+
+ //Req1
+ rparams1 := &test_subs_req_params{}
+ rparams1.Init()
+ cretrans1 := xappConn1.handle_xapp_subs_req(t, rparams1, nil)
+ crereq1, cremsg1 := e2termConn.handle_e2term_subs_req(t)
+
+ //Req2
+ rparams2 := &test_subs_req_params{}
+ rparams2.Init()
+ cretrans2 := xappConn2.handle_xapp_subs_req(t, rparams2, nil)
+
+ //Resp1
+ e2termConn.handle_e2term_subs_resp(t, crereq1, cremsg1)
+ e2SubsId1 := xappConn1.handle_xapp_subs_resp(t, cretrans1)
+
+ //Resp2
+ e2SubsId2 := xappConn2.handle_xapp_subs_resp(t, cretrans2)
+
+ //Del1
+ deltrans1 := xappConn1.handle_xapp_subs_del_req(t, nil, e2SubsId1)
+ xappConn1.handle_xapp_subs_del_resp(t, deltrans1)
+
+ //Del2
+ deltrans2 := xappConn2.handle_xapp_subs_del_req(t, nil, e2SubsId2)
+ delreq2, delmsg2 := e2termConn.handle_e2term_subs_del_req(t)
+ e2termConn.handle_e2term_subs_del_resp(t, delreq2, delmsg2)
+ xappConn2.handle_xapp_subs_del_resp(t, deltrans2)
+
+ //Wait that subs is cleaned
+ mainCtrl.wait_subs_clean(t, e2SubsId2, 10)
+
+ xappConn1.TestMsgCnt(t)
+ xappConn2.TestMsgCnt(t)
+ e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
+}
+
+//-----------------------------------------------------------------------------
+// TestSubReqAndSubDelNokSameActionParallel
+//
+// stub stub
+// +-------+ +---------+ +---------+
+// | xapp | | submgr | | e2term |
+// +-------+ +---------+ +---------+
+// | | |
+// | | |
+// | | |
+// | SubReq1 | |
+// |------------->| |
+// | | |
+// | | SubReq1 |
+// | |------------->|
+// | SubReq2 | |
+// |------------->| |
+// | | SubFail1 |
+// | |<-------------|
+// | SubFail1 | |
+// |<-------------| |
+// | | |
+// | SubFail2 | |
+// |<-------------| |
+//
+//-----------------------------------------------------------------------------
+func TestSubReqAndSubDelNokSameActionParallel(t *testing.T) {
+ xapp.Logger.Info("TestSubReqAndSubDelNokSameActionParallel")
+
+ //Req1
+ rparams1 := &test_subs_req_params{}
+ rparams1.Init()
+ cretrans1 := xappConn1.handle_xapp_subs_req(t, rparams1, nil)
+ crereq1, cremsg1 := e2termConn.handle_e2term_subs_req(t)
+
+ //Req2
+ rparams2 := &test_subs_req_params{}
+ rparams2.Init()
+ seqBef2 := mainCtrl.get_msgcounter(t)
+ cretrans2 := xappConn2.handle_xapp_subs_req(t, rparams2, nil)
+ mainCtrl.wait_msgcounter_change(t, seqBef2, 10)
+
+ //E2T Fail
+ fparams := &test_subs_fail_params{}
+ fparams.Set(crereq1)
+ e2termConn.handle_e2term_subs_fail(t, fparams, cremsg1)
+
+ //Fail1
+ e2SubsId1 := xappConn1.handle_xapp_subs_fail(t, cretrans1)
+ //Fail2
+ xappConn2.handle_xapp_subs_fail(t, cretrans2)
+
+ //Wait that subs is cleaned
+ mainCtrl.wait_subs_clean(t, e2SubsId1, 15)
+
+ xappConn1.TestMsgCnt(t)
+ xappConn2.TestMsgCnt(t)
+ e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 10)
+}
+
+//-----------------------------------------------------------------------------
+// TestSubReqAndSubDelNoAnswerSameActionParallel
+//
+// stub stub
+// +-------+ +---------+ +---------+
+// | xapp | | submgr | | e2term |
+// +-------+ +---------+ +---------+
+// | | |
+// | | |
+// | | |
+// | SubReq1 | |
+// |------------->| |
+// | | |
+// | | SubReq1 |
+// | |------------->|
+// | SubReq2 | |
+// |------------->| |
+// | | |
+// | | SubReq1 |
+// | |------------->|
+// | | |
+// | | |
+// | | SubDelReq |
+// | |------------->|
+// | | |
+// | | SubDelResp |
+// | |<-------------|
+//
+//-----------------------------------------------------------------------------
+func TestSubReqAndSubDelNoAnswerSameActionParallel(t *testing.T) {
+ xapp.Logger.Info("TestSubReqAndSubDelNoAnswerSameActionParallel")
+
+ //Req1
+ rparams1 := &test_subs_req_params{}
+ rparams1.Init()
+ xappConn1.handle_xapp_subs_req(t, rparams1, nil)
+
+ e2termConn.handle_e2term_subs_req(t)
+
+ //Req2
+ rparams2 := &test_subs_req_params{}
+ rparams2.Init()
+ seqBef2 := mainCtrl.get_msgcounter(t)
+ xappConn2.handle_xapp_subs_req(t, rparams2, nil)
+ mainCtrl.wait_msgcounter_change(t, seqBef2, 10)
+
+ //Req1 (retransmitted)
+ e2termConn.handle_e2term_subs_req(t)
+
+ delreq1, delmsg1 := e2termConn.handle_e2term_subs_del_req(t)
+ e2termConn.handle_e2term_subs_del_resp(t, delreq1, delmsg1)
+
+ //Wait that subs is cleaned
+ mainCtrl.wait_subs_clean(t, int(delreq1.RequestId.Seq), 10)
+
+ xappConn1.TestMsgCnt(t)
+ xappConn2.TestMsgCnt(t)
+ e2termConn.TestMsgCnt(t)
+ mainCtrl.wait_registry_empty(t, 15)
}
diff --git a/pkg/control/ut_stub_rtmgr_test.go b/pkg/control/ut_stub_rtmgr_test.go
index bdca293..59467dc 100644
--- a/pkg/control/ut_stub_rtmgr_test.go
+++ b/pkg/control/ut_stub_rtmgr_test.go
@@ -84,12 +84,22 @@
hc.Lock()
defer hc.Unlock()
- var req rtmgr_models.XappSubscriptionData
- err := json.NewDecoder(r.Body).Decode(&req)
- if err != nil {
- xapp.Logger.Error("%s", err.Error())
+ if r.Method == http.MethodPost || r.Method == http.MethodDelete {
+ var req rtmgr_models.XappSubscriptionData
+ err := json.NewDecoder(r.Body).Decode(&req)
+ if err != nil {
+ xapp.Logger.Error("%s", err.Error())
+ }
+ xapp.Logger.Info("(%s) handling SubscriptionID=%d Address=%s Port=%d", hc.desc, *req.SubscriptionID, *req.Address, *req.Port)
}
- xapp.Logger.Info("(%s) handling Address=%s Port=%d SubscriptionID=%d", hc.desc, *req.Address, *req.Port, *req.SubscriptionID)
+ if r.Method == http.MethodPut {
+ var req rtmgr_models.XappList
+ err := json.NewDecoder(r.Body).Decode(&req)
+ if err != nil {
+ xapp.Logger.Error("%s", err.Error())
+ }
+ xapp.Logger.Info("(%s) handling put", hc.desc)
+ }
var code int = 0
switch r.Method {
@@ -107,6 +117,13 @@
code = 400
}
}
+ case http.MethodPut:
+ code = 201
+ if hc.eventWaiter != nil {
+ if hc.eventWaiter.nextActionOk == false {
+ code = 400
+ }
+ }
default:
code = 200
}
diff --git a/pkg/control/ut_stub_xapp_test.go b/pkg/control/ut_stub_xapp_test.go
index a524d9b..331d14d 100644
--- a/pkg/control/ut_stub_xapp_test.go
+++ b/pkg/control/ut_stub_xapp_test.go
@@ -111,7 +111,42 @@
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
-func (xappConn *testingXappStub) handle_xapp_subs_req(t *testing.T, oldTrans *xappTransaction) *xappTransaction {
+type test_subs_req_params struct {
+ req *e2ap.E2APSubscriptionRequest
+}
+
+func (p *test_subs_req_params) Init() {
+ p.req = &e2ap.E2APSubscriptionRequest{}
+
+ p.req.RequestId.Id = 1
+ p.req.RequestId.Seq = 0
+ p.req.FunctionId = 1
+
+ p.req.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present = true
+ p.req.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.StringPut("310150")
+ p.req.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId.Id = 123
+ p.req.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId.Bits = e2ap.E2AP_ENBIDHomeBits28
+
+ // gnb -> enb outgoing
+ // enb -> gnb incoming
+ // X2 36423-f40.doc
+ p.req.EventTriggerDefinition.InterfaceDirection = e2ap.E2AP_InterfaceDirectionIncoming
+ p.req.EventTriggerDefinition.ProcedureCode = 5 //28 35
+ p.req.EventTriggerDefinition.TypeOfMessage = e2ap.E2AP_InitiatingMessage
+
+ p.req.ActionSetups = make([]e2ap.ActionToBeSetupItem, 1)
+ p.req.ActionSetups[0].ActionId = 0
+ p.req.ActionSetups[0].ActionType = e2ap.E2AP_ActionTypeReport
+ p.req.ActionSetups[0].ActionDefinition.Present = false
+ //p.req.ActionSetups[index].ActionDefinition.StyleId = 255
+ //p.req.ActionSetups[index].ActionDefinition.ParamId = 222
+ p.req.ActionSetups[0].SubsequentAction.Present = true
+ p.req.ActionSetups[0].SubsequentAction.Type = e2ap.E2AP_SubSeqActionTypeContinue
+ p.req.ActionSetups[0].SubsequentAction.TimetoWait = e2ap.E2AP_TimeToWaitZero
+
+}
+
+func (xappConn *testingXappStub) handle_xapp_subs_req(t *testing.T, rparams *test_subs_req_params, oldTrans *xappTransaction) *xappTransaction {
xapp.Logger.Info("(%s) handle_xapp_subs_req", xappConn.desc)
e2SubsReq := xapp_e2asnpacker.NewPackerSubscriptionRequest()
@@ -120,35 +155,14 @@
//---------------------------------
xapp.Logger.Info("(%s) Send Subs Req", xappConn.desc)
- req := &e2ap.E2APSubscriptionRequest{}
+ myparams := rparams
- req.RequestId.Id = 1
- req.RequestId.Seq = 0
- req.FunctionId = 1
+ if myparams == nil {
+ myparams = &test_subs_req_params{}
+ myparams.Init()
+ }
- req.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present = true
- req.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.StringPut("310150")
- req.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId.Id = 123
- req.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId.Bits = e2ap.E2AP_ENBIDHomeBits28
-
- // gnb -> enb outgoing
- // enb -> gnb incoming
- // X2 36423-f40.doc
- req.EventTriggerDefinition.InterfaceDirection = e2ap.E2AP_InterfaceDirectionIncoming
- req.EventTriggerDefinition.ProcedureCode = 5 //28 35
- req.EventTriggerDefinition.TypeOfMessage = e2ap.E2AP_InitiatingMessage
-
- req.ActionSetups = make([]e2ap.ActionToBeSetupItem, 1)
- req.ActionSetups[0].ActionId = 0
- req.ActionSetups[0].ActionType = e2ap.E2AP_ActionTypeReport
- req.ActionSetups[0].ActionDefinition.Present = false
- //req.ActionSetups[index].ActionDefinition.StyleId = 255
- //req.ActionSetups[index].ActionDefinition.ParamId = 222
- req.ActionSetups[0].SubsequentAction.Present = true
- req.ActionSetups[0].SubsequentAction.Type = e2ap.E2AP_SubSeqActionTypeContinue
- req.ActionSetups[0].SubsequentAction.TimetoWait = e2ap.E2AP_TimeToWaitZero
-
- e2SubsReq.Set(req)
+ e2SubsReq.Set(myparams.req)
xapp.Logger.Debug("%s", e2SubsReq.String())
err, packedMsg := e2SubsReq.Pack(nil)
if err != nil {
@@ -327,7 +341,7 @@
if msg.Mtype != xapp.RICMessageTypes["RIC_SUB_DEL_RESP"] {
testError(t, "(%s) Received RIC_SUB_DEL_RESP wrong mtype expected %s got %s, error", xappConn.desc, "RIC_SUB_DEL_RESP", xapp.RicMessageTypeToName[msg.Mtype])
return
- } else if msg.Xid != trans.xid {
+ } else if trans != nil && msg.Xid != trans.xid {
testError(t, "(%s) Received RIC_SUB_DEL_RESP wrong xid expected %s got %s, error", xappConn.desc, trans.xid, msg.Xid)
return
} else {