RICPLT-3015 Reusing subscription if same EventTrigger and Action
[ric-plt/submgr.git] / pkg / control / subscription.go
index 4514d00..5bfe2e1 100644 (file)
 package control
 
 import (
-       "fmt"
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        "strconv"
        "sync"
-       "time"
 )
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
 type Subscription struct {
-       mutex      sync.Mutex      // Lock
-       registry   *Registry       // Registry
-       Seq        uint16          // SubsId
-       Meid       *xapp.RMRMeid   // Meid/ RanName
-       EpList     RmrEndpointList // Endpoints
-       DelEpList  RmrEndpointList // Endpoints
-       DelSeq     uint64
+       mutex      sync.Mutex                     // Lock
+       valid      bool                           // valid
+       registry   *Registry                      // Registry
+       Seq        uint16                         // SubsId
+       Meid       *xapp.RMRMeid                  // Meid/ RanName
+       EpList     RmrEndpointList                // Endpoints
        TransLock  sync.Mutex                     // Lock transactions, only one executed per time for subs
        TheTrans   *Transaction                   // Ongoing transaction from xapp
        SubReqMsg  *e2ap.E2APSubscriptionRequest  // Subscription information
        SubRespMsg *e2ap.E2APSubscriptionResponse // Subscription information
-}
-
-func (s *Subscription) stringImpl() string {
-       return "subs(" + strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.Meid.RanName + "/" + s.EpList.String() + ")"
+       SubFailMsg *e2ap.E2APSubscriptionFailure  // Subscription information
 }
 
 func (s *Subscription) String() string {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       return s.stringImpl()
+       return "subs(" + strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.Meid.RanName + "/" + s.EpList.String() + ")"
 }
 
 func (s *Subscription) GetSubId() uint16 {
@@ -70,68 +62,6 @@ func (s *Subscription) GetMeid() *xapp.RMRMeid {
        return nil
 }
 
-func (s *Subscription) AddEndpoint(ep *RmrEndpoint) error {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       if ep == nil {
-               return fmt.Errorf("AddEndpoint no endpoint given")
-       }
-       if s.EpList.AddEndpoint(ep) {
-               s.DelEpList.DelEndpoint(ep)
-               if s.EpList.Size() == 1 {
-                       return s.updateRouteImpl(CREATE)
-               }
-               return s.updateRouteImpl(MERGE)
-       }
-       return nil
-}
-
-func (s *Subscription) DelEndpoint(ep *RmrEndpoint) error {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       var err error
-       if ep == nil {
-               return fmt.Errorf("DelEndpoint no endpoint given")
-       }
-       if s.EpList.HasEndpoint(ep) == false {
-               return fmt.Errorf("DelEndpoint endpoint not found")
-       }
-       if s.DelEpList.HasEndpoint(ep) == true {
-               return fmt.Errorf("DelEndpoint endpoint already under del")
-       }
-       s.DelEpList.AddEndpoint(ep)
-       go s.CleanCheck()
-       return err
-}
-
-func (s *Subscription) CleanCheck() {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       s.DelSeq++
-       // Only one clean ongoing
-       if s.DelSeq > 1 {
-               return
-       }
-       var currSeq uint64 = 0
-       // Make sure that routes to be deleted
-       // are not deleted too fast
-       for currSeq < s.DelSeq {
-               currSeq = s.DelSeq
-               s.mutex.Unlock()
-               time.Sleep(5 * time.Second)
-               s.mutex.Lock()
-       }
-       xapp.Logger.Info("DelEndpoint: delete cleaning %s", s.stringImpl())
-       if s.EpList.Size() <= s.DelEpList.Size() {
-               s.updateRouteImpl(DELETE)
-               go s.registry.DelSubscription(s.Seq)
-       } else if s.EpList.DelEndpoints(&s.DelEpList) {
-               s.updateRouteImpl(MERGE)
-       }
-       s.DelSeq = 0
-
-}
-
 func (s *Subscription) IsTransactionReserved() bool {
        s.mutex.Lock()
        defer s.mutex.Unlock()
@@ -164,11 +94,80 @@ func (s *Subscription) ReleaseTransactionTurn(trans *Transaction) {
        s.TransLock.Unlock()
 }
 
-func (s *Subscription) updateRouteImpl(act Action) error {
-       subRouteAction := SubRouteInfo{act, s.EpList, s.Seq}
-       err := s.registry.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
-       if err != nil {
-               return fmt.Errorf("%s %s", s.stringImpl(), err.Error())
+func (s *Subscription) IsSame(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
+       s.mutex.Lock()
+       defer s.mutex.Unlock()
+
+       if s.valid == false {
+               return false
        }
-       return nil
+
+       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
 }