Subscription REST interface update
[ric-plt/submgr.git] / pkg / control / subscription.go
index 6ed3d32..1152520 100644 (file)
@@ -20,9 +20,9 @@
 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"
 )
 
@@ -30,95 +30,143 @@ import (
 //
 //-----------------------------------------------------------------------------
 type Subscription struct {
-       mutex  sync.Mutex
-       Seq    uint16
-       Active bool
-       //
-       Meid        *xapp.RMRMeid
-       RmrEndpoint // xapp endpoint. Now only one xapp can have relation to single subscription. To be changed in merge
-       Trans       *Transaction
+       mutex            sync.Mutex                    // Lock
+       valid            bool                          // valid
+       registry         *Registry                     // Registry
+       ReqId            RequestId                     // ReqId (Requestor Id + Seq Nro a.k.a subsid)
+       Meid             *xapp.RMRMeid                 // Meid/RanName
+       EpList           xapp.RmrEndpointList          // Endpoints
+       RMRRouteCreated  bool                          // Does subscription have RMR route
+       TransLock        sync.Mutex                    // Lock transactions, only one executed per time for subs
+       TheTrans         TransactionIf                 // Ongoing transaction
+       SubReqMsg        *e2ap.E2APSubscriptionRequest // Subscription information
+       SubRFMsg         interface{}                   // Subscription information
+       PolicyUpdate     bool                          // This is true when policy subscrition is being updated. Used not to send delete for update after timeout or restart
+       RetryFromXapp    bool                          // Retry form xApp for subscription that already exist
+       SubRespRcvd      bool                          // Subscription response received
+       DeleteFromDb     bool                          // Delete subscription from db
+       NoRespToXapp     bool                          // Send no response for subscription delete to xApp after restart
+       DoNotWaitSubResp bool                          // Test flag. Response is not waited for Subscription Request
 }
 
 func (s *Subscription) String() string {
+       meidstr := "N/A"
+       if s.Meid != nil {
+               meidstr = s.Meid.String()
+       }
+       return "subs(" + s.ReqId.String() + "/" + meidstr + "/" + s.EpList.String() + ")"
+}
+
+func (s *Subscription) GetCachedResponse() (interface{}, bool) {
        s.mutex.Lock()
        defer s.mutex.Unlock()
-       return strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.RmrEndpoint.String() + "/" + s.Meid.RanName
+       return s.SubRFMsg, s.valid
 }
 
-func (s *Subscription) GetSubId() uint16 {
+func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
        s.mutex.Lock()
        defer s.mutex.Unlock()
-       return s.Seq
+       s.SubRFMsg = subRFMsg
+       s.valid = valid
+       return s.SubRFMsg, s.valid
 }
 
-func (s *Subscription) GetMeid() *xapp.RMRMeid {
+func (s *Subscription) GetReqId() *RequestId {
        s.mutex.Lock()
        defer s.mutex.Unlock()
-       if s.Meid != nil {
-               return s.Meid
-       }
-       return nil
+       return &s.ReqId
 }
 
-func (s *Subscription) Confirmed() {
+func (s *Subscription) GetMeid() *xapp.RMRMeid {
        s.mutex.Lock()
        defer s.mutex.Unlock()
-       s.Active = true
+       return s.Meid
 }
 
-func (s *Subscription) UnConfirmed() {
+func (s *Subscription) GetTransaction() TransactionIf {
        s.mutex.Lock()
        defer s.mutex.Unlock()
-       s.Active = false
+       return s.TheTrans
 }
 
-func (s *Subscription) IsConfirmed() bool {
+func (s *Subscription) WaitTransactionTurn(trans TransactionIf) {
+       s.TransLock.Lock()
        s.mutex.Lock()
-       defer s.mutex.Unlock()
-       return s.Active
+       s.TheTrans = trans
+       s.mutex.Unlock()
+}
+
+func (s *Subscription) ReleaseTransactionTurn(trans TransactionIf) {
+       s.mutex.Lock()
+       if trans != nil && trans == s.TheTrans {
+               s.TheTrans = nil
+       }
+       s.mutex.Unlock()
+       s.TransLock.Unlock()
 }
 
-func (s *Subscription) SetTransaction(trans *Transaction) error {
+func (s *Subscription) IsMergeable(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
        s.mutex.Lock()
        defer s.mutex.Unlock()
 
-       subString := strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.RmrEndpoint.String() + "/" + s.Meid.RanName
+       if s.valid == false {
+               return false
+       }
 
-       if (s.RmrEndpoint.Addr != trans.RmrEndpoint.Addr) || (s.RmrEndpoint.Port != trans.RmrEndpoint.Port) {
-               return fmt.Errorf("Subscription: %s endpoint mismatch with trans: %s", subString, trans)
+       if s.SubReqMsg == nil {
+               return false
        }
-       if s.Trans != nil {
-               return fmt.Errorf("Subscription: %s trans %s exist, can not register %s", subString, s.Trans, trans)
+
+       if s.Meid.RanName != trans.Meid.RanName {
+               return false
        }
-       trans.Subs = s
-       s.Trans = trans
-       return nil
-}
 
-func (s *Subscription) UnSetTransaction(trans *Transaction) bool {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       if trans == nil || trans == s.Trans {
-               s.Trans = nil
-               return true
+       // EventTrigger check
+       if s.SubReqMsg.EventTriggerDefinition.Data.Length != subReqMsg.EventTriggerDefinition.Data.Length {
+               return false
+       }
+       for i := uint64(0); i < s.SubReqMsg.EventTriggerDefinition.Data.Length; i++ {
+               if s.SubReqMsg.EventTriggerDefinition.Data.Data[i] != subReqMsg.EventTriggerDefinition.Data.Data[i] {
+                       return false
+               }
        }
-       return false
-}
 
-func (s *Subscription) GetTransaction() *Transaction {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       return s.Trans
-}
+       // Actions check
+       if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
+               return false
+       }
 
-func (s *Subscription) UpdateRoute(act Action, rtmgrClient *RtmgrClient) error {
-       s.mutex.Lock()
-       defer s.mutex.Unlock()
-       xapp.Logger.Info("Subscription: Starting routing manager route add. SubId: %d, RmrEndpoint: %s", s.Seq, s.RmrEndpoint)
-       subRouteAction := SubRouteInfo{act, s.RmrEndpoint.Addr, s.RmrEndpoint.Port, s.Seq}
-       err := rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
-       if err != nil {
-               return fmt.Errorf("Subscription: Failed to add route. SubId: %d, RmrEndpoint: %s", s.Seq, s.RmrEndpoint)
+       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.ActionType != e2ap.E2AP_ActionTypeReport {
+                               return false
+                       }
+
+                       if acts.RicActionDefinitionPresent != actt.RicActionDefinitionPresent {
+                               return false
+                       }
+
+                       if acts.ActionDefinitionChoice.Data.Length != actt.ActionDefinitionChoice.Data.Length {
+                               return false
+                       }
+                       for i := uint64(0); i < acts.ActionDefinitionChoice.Data.Length; i++ {
+                               if acts.ActionDefinitionChoice.Data.Data[i] != actt.ActionDefinitionChoice.Data.Data[i] {
+                                       return false
+                               }
+                       }
+                       if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
+                               acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
+                               acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
+                               return false
+                       }
+               }
        }
-       return nil
+       return true
 }