X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=pkg%2Fcontrol%2Fcontrol.go;h=a2c8b0d5d84acb812c6154ae237d2848a7ca0392;hb=422d018f94aedd9f4c001176b5ff06c786de28eb;hp=1bc2ee86de8588e186c0f19009a3ddc559268de8;hpb=31797b49985822f1d402501f16ab2794838bebba;p=ric-plt%2Fsubmgr.git diff --git a/pkg/control/control.go b/pkg/control/control.go index 1bc2ee8..a2c8b0d 100755 --- a/pkg/control/control.go +++ b/pkg/control/control.go @@ -36,10 +36,12 @@ import ( // //----------------------------------------------------------------------------- -var subReqTime time.Duration = 5 * time.Second -var subDelReqTime time.Duration = 5 * time.Second -var maxSubReqTryCount uint64 = 2 // Initial try + retry -var maxSubDelReqTryCount uint64 = 2 // Initial try + retry +var e2tSubReqTimeout time.Duration = 5 * time.Second +var e2tSubDelReqTime time.Duration = 5 * time.Second +var e2tMaxSubReqTryCount uint64 = 2 // Initial try + retry +var e2tMaxSubDelReqTryCount uint64 = 2 // Initial try + retry + +var e2tRecvMsgTimeout time.Duration = 5 * time.Second type Control struct { e2ap *E2ap @@ -157,17 +159,17 @@ func (c *Control) Consume(params *xapp.RMRParams) (err error) { c.msgCounter++ switch msg.Mtype { case xapp.RICMessageTypes["RIC_SUB_REQ"]: - go c.handleSubscriptionRequest(msg) + go c.handleXAPPSubscriptionRequest(msg) case xapp.RICMessageTypes["RIC_SUB_RESP"]: - go c.handleSubscriptionResponse(msg) + go c.handleE2TSubscriptionResponse(msg) case xapp.RICMessageTypes["RIC_SUB_FAILURE"]: - go c.handleSubscriptionFailure(msg) + go c.handleE2TSubscriptionFailure(msg) case xapp.RICMessageTypes["RIC_SUB_DEL_REQ"]: - go c.handleSubscriptionDeleteRequest(msg) + go c.handleXAPPSubscriptionDeleteRequest(msg) case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]: - go c.handleSubscriptionDeleteResponse(msg) + go c.handleE2TSubscriptionDeleteResponse(msg) case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]: - go c.handleSubscriptionDeleteFailure(msg) + go c.handleE2TSubscriptionDeleteFailure(msg) default: xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype) } @@ -188,397 +190,371 @@ func idstring(trans fmt.Stringer, subs fmt.Stringer, err error) string { if err != nil { retval += filler + "err(" + err.Error() + ")" filler = " " - } - return retval -} - -func (c *Control) findSubs(ids []int) (*Subscription, error) { - var subs *Subscription = nil - for _, id := range ids { - if id >= 0 { - subs = c.registry.GetSubscription(uint16(id)) - } - if subs != nil { - break - } - } - if subs == nil { - return nil, fmt.Errorf("No valid subscription found with ids %v", ids) - } - return subs, nil -} -func (c *Control) findSubsAndTrans(ids []int) (*Subscription, *Transaction, error) { - subs, err := c.findSubs(ids) - if err != nil { - return nil, nil, err - } - trans := subs.GetTransaction() - if trans == nil { - return subs, nil, fmt.Errorf("No ongoing transaction found from %s", idstring(nil, subs, nil)) } - return subs, trans, nil + return retval } -func (c *Control) handleSubscriptionRequest(params *RMRParams) { - xapp.Logger.Info("SubReq from xapp: %s", params.String()) +//------------------------------------------------------------------- +// handle from XAPP Subscription Request +//------------------------------------------------------------------ +func (c *Control) handleXAPPSubscriptionRequest(params *RMRParams) { + xapp.Logger.Info("XAPP-SubReq from xapp: %s", params.String()) - SubReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload) + subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload) if err != nil { - xapp.Logger.Error("SubReq Drop: %s", idstring(params, nil, err)) + xapp.Logger.Error("XAPP-SubReq: %s", idstring(params, nil, err)) return } - trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid, false, true) + trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid) if err != nil { - xapp.Logger.Error("SubReq Drop: %s", idstring(params, nil, err)) + xapp.Logger.Error("XAPP-SubReq: %s", idstring(params, nil, err)) return } - trans.SubReqMsg = SubReqMsg + defer trans.Release() - subs, err := c.registry.ReserveSubscription(trans.Meid) + subs, err := c.registry.AssignToSubscription(trans, subReqMsg) if err != nil { - xapp.Logger.Error("SubReq Drop: %s", idstring(trans, nil, err)) - trans.Release() + xapp.Logger.Error("XAPP-SubReq: %s", idstring(trans, nil, err)) return } - err = subs.SetTransaction(trans) - if err != nil { - xapp.Logger.Error("SubReq Drop: %s", idstring(trans, subs, err)) - subs.Release() - trans.Release() + 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 } - trans.SubReqMsg.RequestId.Seq = uint32(subs.GetSubId()) - - xapp.Logger.Debug("SubReq: Handling %s", idstring(trans, subs, nil)) // - // TODO: subscription create is in fact owned by subscription and not transaction. - // Transaction is toward xapp while Subscription is toward ran. - // In merge several xapps may wake transactions, while only one subscription - // toward ran occurs -> subscription owns subscription creation toward ran + // Wake subs request // - // This is intermediate solution while improving message handling - // - trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(trans.SubReqMsg) - if err != nil { - xapp.Logger.Error("SubResp Drop: %s", idstring(trans, subs, err)) - subs.Release() - trans.Release() - return + 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.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(themsg) + if err == nil { + c.rmrReplyToSender("XAPP-SubReq: SubResp to xapp", subs, trans) + return + } + case *e2ap.E2APSubscriptionFailure: + trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(themsg) + if err == nil { + c.rmrReplyToSender("XAPP-SubReq: SubFail to xapp", subs, trans) + } + return + default: + break + } } - - c.rmrSend("SubReq: SubReq to E2T", subs, trans) - c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, FirstTry, c.handleSubscriptionRequestTimer) - return + xapp.Logger.Info("XAPP-SubReq: failed %s", idstring(trans, subs, err)) } -func (c *Control) handleSubscriptionResponse(params *RMRParams) { - xapp.Logger.Info("SubResp from E2T: %s", params.String()) +//------------------------------------------------------------------- +// handle from XAPP Subscription Delete Request +//------------------------------------------------------------------ +func (c *Control) handleXAPPSubscriptionDeleteRequest(params *RMRParams) { + xapp.Logger.Info("XAPP-SubDelReq from xapp: %s", params.String()) - SubRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload) + subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload) if err != nil { - xapp.Logger.Error("SubResp Drop %s", idstring(params, nil, err)) + xapp.Logger.Error("XAPP-SubDelReq %s", idstring(params, nil, err)) return } - subs, trans, err := c.findSubsAndTrans([]int{int(SubRespMsg.RequestId.Seq), params.SubId}) + trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid) if err != nil { - xapp.Logger.Error("SubResp: %s", idstring(params, nil, err)) + xapp.Logger.Error("XAPP-SubDelReq %s", idstring(params, nil, err)) return } - trans.SubRespMsg = SubRespMsg - xapp.Logger.Debug("SubResp: Handling %s", idstring(trans, subs, nil)) + defer trans.Release() - c.timerMap.StopTimer("RIC_SUB_REQ", int(subs.GetSubId())) - - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription timer already received - return - } - - trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(trans.SubRespMsg) - if err != nil { - xapp.Logger.Error("SubResp: %s", idstring(trans, subs, err)) - trans.Release() - return - } - - subs.Confirmed() - trans.Release() - c.rmrReplyToSender("SubResp: SubResp to xapp", subs, trans) - return -} - -func (c *Control) handleSubscriptionFailure(params *RMRParams) { - xapp.Logger.Info("SubFail from E2T: %s", params.String()) - - SubFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload) + subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelReqMsg.RequestId.Seq), uint16(params.SubId)}) if err != nil { - xapp.Logger.Error("SubFail Drop %s", idstring(params, nil, err)) + xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(trans, nil, err)) return } - subs, trans, err := c.findSubsAndTrans([]int{int(SubFailMsg.RequestId.Seq), params.SubId}) - if err != nil { - xapp.Logger.Error("SubFail: %s", idstring(params, nil, err)) + 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 } - trans.SubFailMsg = SubFailMsg - xapp.Logger.Debug("SubFail: Handling %s", idstring(trans, subs, nil)) - c.timerMap.StopTimer("RIC_SUB_REQ", int(subs.GetSubId())) - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription timer already received - return - } - - trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(trans.SubFailMsg) + // + // Wake subs delete + // + go c.handleSubscriptionDelete(subs, trans) + trans.WaitEvent(0) //blocked wait as timeout is handled in subs side + + // Whatever is received send ok delete response + subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{} + subDelRespMsg.RequestId.Id = subs.SubReqMsg.RequestId.Id + subDelRespMsg.RequestId.Seq = uint32(subs.GetSubId()) + subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId + trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(subDelRespMsg) if err == nil { - c.rmrReplyToSender("SubFail: SubFail to xapp", subs, trans) - time.Sleep(3 * time.Second) - } else { - //TODO error handling improvement - xapp.Logger.Error("SubFail: (continue cleaning) %s", idstring(trans, subs, err)) + c.rmrReplyToSender("XAPP-SubDelReq: SubDelResp to xapp", subs, trans) } - - trans.Release() - subs.Release() - return } -func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int, tryCount uint64) { - xapp.Logger.Info("SubReq timeout: subId: %v, tryCount: %v", nbrId, tryCount) +//------------------------------------------------------------------- +// SUBS CREATE Handling +//------------------------------------------------------------------- +func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *Transaction) { - subs, trans, err := c.findSubsAndTrans(([]int{nbrId})) - if err != nil { - xapp.Logger.Error("SubReq timeout: %s", idstring(nil, nil, err)) + trans := c.tracker.NewTransaction(subs.GetMeid()) + subs.WaitTransactionTurn(trans) + defer subs.ReleaseTransactionTurn(trans) + defer trans.Release() + + xapp.Logger.Debug("SUBS-SubReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String()) + + if subs.SubRespMsg != nil { + xapp.Logger.Debug("SUBS-SubReq: Handling (immediate response) %s parent %s", idstring(nil, subs, nil), parentTrans.String()) + parentTrans.SendEvent(subs.SubRespMsg, 0) return } - xapp.Logger.Debug("SubReq timeout: Handling %s", idstring(trans, subs, nil)) - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription Response or Failure already received + event := c.sendE2TSubscriptionRequest(subs, trans, parentTrans) + switch themsg := event.(type) { + case *e2ap.E2APSubscriptionResponse: + subs.SubRespMsg = themsg + parentTrans.SendEvent(event, 0) return + case *e2ap.E2APSubscriptionFailure: + //TODO: Possible delete and one retry for subs req + parentTrans.SendEvent(event, 0) + default: + xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(trans, subs, nil)) + c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans) + parentTrans.SendEvent(nil, 0) } - if tryCount < maxSubReqTryCount { - xapp.Logger.Info("SubReq timeout: %s", idstring(trans, subs, nil)) + subs.DelEndpoint(parentTrans.GetEndpoint()) +} - trans.RetryTransaction() +//------------------------------------------------------------------- +// SUBS DELETE Handling +//------------------------------------------------------------------- +func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *Transaction) { - c.rmrSend("SubReq timeout: SubReq to E2T", subs, trans) + trans := c.tracker.NewTransaction(subs.GetMeid()) + subs.WaitTransactionTurn(trans) + defer subs.ReleaseTransactionTurn(trans) + defer trans.Release() - tryCount++ - c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionRequestTimer) - return - } + xapp.Logger.Debug("SUBS-SubDelReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String()) - // Release CREATE transaction - trans.Release() + event := c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans) - // Create DELETE transaction (internal and no messages toward xapp) - deltrans, err := c.tracker.TrackTransaction(&trans.RmrEndpoint, trans.GetXid(), trans.GetMeid(), false, false) - if err != nil { - xapp.Logger.Error("SubReq timeout: %s", idstring(trans, subs, err)) - //TODO improve error handling. Important at least in merge - subs.Release() - return - } + parentTrans.SendEvent(event, 0) + subs.DelEndpoint(parentTrans.GetEndpoint()) +} - deltrans.SubDelReqMsg = &e2ap.E2APSubscriptionDeleteRequest{} - deltrans.SubDelReqMsg.RequestId.Id = trans.SubReqMsg.RequestId.Id - deltrans.SubDelReqMsg.RequestId.Seq = uint32(subs.GetSubId()) - deltrans.SubDelReqMsg.FunctionId = trans.SubReqMsg.FunctionId - deltrans.Mtype, deltrans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(deltrans.SubDelReqMsg) +//------------------------------------------------------------------- +// send to E2T Subscription Request +//------------------------------------------------------------------- +func (c *Control) sendE2TSubscriptionRequest(subs *Subscription, trans *Transaction, parentTrans *Transaction) interface{} { + var err error + var event interface{} = nil + var timedOut bool = false + + subReqMsg := subs.SubReqMsg + subReqMsg.RequestId.Id = 123 + subReqMsg.RequestId.Seq = uint32(subs.GetSubId()) + trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(subReqMsg) if err != nil { - xapp.Logger.Error("SubReq timeout: %s", idstring(trans, subs, err)) - //TODO improve error handling. Important at least in merge - deltrans.Release() - subs.Release() - return + xapp.Logger.Error("SUBS-SubReq: %s parent %s", idstring(trans, subs, err), parentTrans.String()) + return event } - err = subs.SetTransaction(deltrans) - if err != nil { - xapp.Logger.Error("SubReq timeout: %s", idstring(trans, subs, err)) - //TODO improve error handling. Important at least in merge - deltrans.Release() - return + for retries := uint64(0); retries < e2tMaxSubReqTryCount; retries++ { + desc := fmt.Sprintf("SUBS-SubReq: SubReq to E2T (retry %d)", retries) + c.rmrSend(desc, subs, trans) + event, timedOut = trans.WaitEvent(e2tSubReqTimeout) + if timedOut { + continue + } + break } - - c.rmrSend("SubReq timer: SubDelReq to E2T", subs, deltrans) - c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer) - return + xapp.Logger.Debug("SUBS-SubReq: Response handling event(%s) %s parent %s", typeofSubsMessage(event), idstring(trans, subs, nil), parentTrans.String()) + return event } -func (c *Control) handleSubscriptionDeleteRequest(params *RMRParams) { - xapp.Logger.Info("SubDelReq from xapp: %s", params.String()) +//------------------------------------------------------------------- +// send to E2T Subscription Delete Request +//------------------------------------------------------------------- - SubDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload) +func (c *Control) sendE2TSubscriptionDeleteRequest(subs *Subscription, trans *Transaction, parentTrans *Transaction) interface{} { + var err error + var event interface{} + var timedOut bool + + subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{} + subDelReqMsg.RequestId.Id = 123 + subDelReqMsg.RequestId.Seq = uint32(subs.GetSubId()) + subDelReqMsg.FunctionId = 0 + trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg) if err != nil { - xapp.Logger.Error("SubDelReq Drop %s", idstring(params, nil, err)) - return + xapp.Logger.Error("SUBS-SubDelReq: %s parent %s", idstring(trans, subs, err), parentTrans.String()) + return event } - trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid, false, true) - if err != nil { - xapp.Logger.Error("SubDelReq Drop %s", idstring(params, nil, err)) - return + for retries := uint64(0); retries < e2tMaxSubDelReqTryCount; retries++ { + desc := fmt.Sprintf("SUBS-SubDelReq: SubDelReq to E2T (retry %d)", retries) + c.rmrSend(desc, subs, trans) + event, timedOut = trans.WaitEvent(e2tSubDelReqTime) + if timedOut { + continue + } + break } - trans.SubDelReqMsg = SubDelReqMsg + xapp.Logger.Debug("SUBS-SubDelReq: Response handling event(%s) %s parent %s", typeofSubsMessage(event), idstring(trans, subs, nil), parentTrans.String()) + return event +} - subs, err := c.findSubs([]int{int(trans.SubDelReqMsg.RequestId.Seq), params.SubId}) +//------------------------------------------------------------------- +// handle from E2T Subscription Reponse +//------------------------------------------------------------------- +func (c *Control) handleE2TSubscriptionResponse(params *RMRParams) { + xapp.Logger.Info("MSG-SubResp from E2T: %s", params.String()) + subRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload) if err != nil { - xapp.Logger.Error("SubDelReq: %s", idstring(params, nil, err)) - trans.Release() + xapp.Logger.Error("MSG-SubResp %s", idstring(params, nil, err)) return } - - err = subs.SetTransaction(trans) + subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subRespMsg.RequestId.Seq), uint16(params.SubId)}) if err != nil { - xapp.Logger.Error("SubDelReq: %s", idstring(trans, subs, err)) - trans.Release() + xapp.Logger.Error("MSG-SubResp: %s", idstring(params, nil, err)) return } - - xapp.Logger.Debug("SubDelReq: Handling %s", idstring(trans, subs, nil)) - - // - // TODO: subscription delete is in fact owned by subscription and not transaction. - // Transaction is toward xapp while Subscription is toward ran. - // In merge several xapps may wake transactions, while only one subscription - // toward ran occurs -> subscription owns subscription creation toward ran - // - // This is intermediate solution while improving message handling - // - trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(trans.SubDelReqMsg) - if err != nil { - xapp.Logger.Error("SubDelReq: %s", idstring(trans, subs, err)) - trans.Release() + trans := subs.GetTransaction() + if trans == nil { + err = fmt.Errorf("Ongoing transaction not found") + xapp.Logger.Error("MSG-SubResp: %s", idstring(params, subs, err)) return } - - subs.UnConfirmed() - - c.rmrSend("SubDelReq: SubDelReq to E2T", subs, trans) - - c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer) + sendOk, timedOut := trans.SendEvent(subRespMsg, e2tRecvMsgTimeout) + if sendOk == false { + err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut) + xapp.Logger.Error("MSG-SubResp: %s", idstring(trans, subs, err)) + } return } -func (c *Control) handleSubscriptionDeleteResponse(params *RMRParams) (err error) { - xapp.Logger.Info("SubDelResp from E2T:%s", params.String()) - - SubDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload) +//------------------------------------------------------------------- +// handle from E2T Subscription Failure +//------------------------------------------------------------------- +func (c *Control) handleE2TSubscriptionFailure(params *RMRParams) { + xapp.Logger.Info("MSG-SubFail from E2T: %s", params.String()) + subFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload) if err != nil { - xapp.Logger.Error("SubDelResp: Dropping this msg. %s", idstring(params, nil, err)) + xapp.Logger.Error("MSG-SubFail %s", idstring(params, nil, err)) return } - - subs, trans, err := c.findSubsAndTrans([]int{int(SubDelRespMsg.RequestId.Seq), params.SubId}) + subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subFailMsg.RequestId.Seq), uint16(params.SubId)}) if err != nil { - xapp.Logger.Error("SubDelResp: %s", idstring(params, nil, err)) + xapp.Logger.Error("MSG-SubFail: %s", idstring(params, nil, err)) return } - trans.SubDelRespMsg = SubDelRespMsg - xapp.Logger.Debug("SubDelResp: Handling %s", idstring(trans, subs, nil)) - - c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId())) - - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription Delete timer already received + trans := subs.GetTransaction() + if trans == nil { + err = fmt.Errorf("Ongoing transaction not found") + xapp.Logger.Error("MSG-SubFail: %s", idstring(params, subs, err)) return } - - c.sendSubscriptionDeleteResponse("SubDelResp", trans, subs) + sendOk, timedOut := trans.SendEvent(subFailMsg, e2tRecvMsgTimeout) + if sendOk == false { + err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut) + xapp.Logger.Error("MSG-SubFail: %s", idstring(trans, subs, err)) + } return } -func (c *Control) handleSubscriptionDeleteFailure(params *RMRParams) { - xapp.Logger.Info("SubDelFail from E2T:%s", params.String()) - - SubDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload) +//------------------------------------------------------------------- +// handle from E2T Subscription Delete Response +//------------------------------------------------------------------- +func (c *Control) handleE2TSubscriptionDeleteResponse(params *RMRParams) (err error) { + xapp.Logger.Info("SUBS-SubDelResp from E2T:%s", params.String()) + subDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload) if err != nil { - xapp.Logger.Error("SubDelFail: Dropping this msg. %s", idstring(params, nil, err)) + xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, nil, err)) return } - - subs, trans, err := c.findSubsAndTrans([]int{int(SubDelFailMsg.RequestId.Seq), params.SubId}) + subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelRespMsg.RequestId.Seq), uint16(params.SubId)}) if err != nil { - xapp.Logger.Error("SubDelFail: %s", idstring(params, nil, err)) + xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, nil, err)) return } - trans.SubDelFailMsg = SubDelFailMsg - xapp.Logger.Debug("SubDelFail: Handling %s", idstring(trans, subs, nil)) - - c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId())) - - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription Delete timer already received + trans := subs.GetTransaction() + if trans == nil { + err = fmt.Errorf("Ongoing transaction not found") + xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, subs, err)) return } - - c.sendSubscriptionDeleteResponse("SubDelFail", trans, subs) + sendOk, timedOut := trans.SendEvent(subDelRespMsg, e2tRecvMsgTimeout) + if sendOk == false { + err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut) + xapp.Logger.Error("MSG-SubDelResp: %s", idstring(trans, subs, err)) + } return } -func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) { - xapp.Logger.Info("SubDelReq timeout: subId: %v, tryCount: %v", nbrId, tryCount) - - subs, trans, err := c.findSubsAndTrans([]int{nbrId}) +//------------------------------------------------------------------- +// handle from E2T Subscription Delete Failure +//------------------------------------------------------------------- +func (c *Control) handleE2TSubscriptionDeleteFailure(params *RMRParams) { + xapp.Logger.Info("MSG-SubDelFail from E2T:%s", params.String()) + subDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload) if err != nil { - xapp.Logger.Error("SubDelReq timeout: %s", idstring(nil, nil, err)) + xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, nil, err)) return } - xapp.Logger.Debug("SubDelReq timeout: Handling %s", idstring(trans, subs, nil)) - - responseReceived := trans.CheckResponseReceived() - if responseReceived == true { - // Subscription Delete Response or Failure already received + subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelFailMsg.RequestId.Seq), uint16(params.SubId)}) + if err != nil { + xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, nil, err)) return } - - if tryCount < maxSubDelReqTryCount { - // Set possible to handle new response for the subId - trans.RetryTransaction() - c.rmrSend("SubDelReq timeout: SubDelReq to E2T", subs, trans) - tryCount++ - c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer) + trans := subs.GetTransaction() + if trans == nil { + err = fmt.Errorf("Ongoing transaction not found") + xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, subs, err)) return } - - c.sendSubscriptionDeleteResponse("SubDelReq(timer)", trans, subs) + sendOk, timedOut := trans.SendEvent(subDelFailMsg, e2tRecvMsgTimeout) + if sendOk == false { + err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut) + xapp.Logger.Error("MSG-SubDelFail: %s", idstring(trans, subs, err)) + } return } -func (c *Control) sendSubscriptionDeleteResponse(desc string, trans *Transaction, subs *Subscription) { - - if trans.ForwardRespToXapp == true { - //Always generate SubDelResp - trans.SubDelRespMsg = &e2ap.E2APSubscriptionDeleteResponse{} - trans.SubDelRespMsg.RequestId.Id = trans.SubDelReqMsg.RequestId.Id - trans.SubDelRespMsg.RequestId.Seq = uint32(subs.GetSubId()) - trans.SubDelRespMsg.FunctionId = trans.SubDelReqMsg.FunctionId - - var err error - trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(trans.SubDelRespMsg) - if err == nil { - c.rmrReplyToSender(desc+": SubDelResp to xapp", subs, trans) - time.Sleep(3 * time.Second) - } else { - //TODO error handling improvement - xapp.Logger.Error("%s: (continue cleaning) %s", desc, idstring(trans, subs, err)) - } +//------------------------------------------------------------------- +// +//------------------------------------------------------------------- +func typeofSubsMessage(v interface{}) string { + if v == nil { + return "NIL" + } + switch v.(type) { + case *e2ap.E2APSubscriptionRequest: + return "SubReq" + case *e2ap.E2APSubscriptionResponse: + return "SubResp" + case *e2ap.E2APSubscriptionFailure: + return "SubFail" + case *e2ap.E2APSubscriptionDeleteRequest: + return "SubDelReq" + case *e2ap.E2APSubscriptionDeleteResponse: + return "SubDelResp" + case *e2ap.E2APSubscriptionDeleteFailure: + return "SubDelFail" + default: + return "Unknown" } - - trans.Release() - subs.Release() }