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 {