E2 restart handling added
[ric-plt/submgr.git] / pkg / control / subscription.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
24         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
25
26         "sync"
27 )
28
29 //-----------------------------------------------------------------------------
30 //
31 //-----------------------------------------------------------------------------
32 type Subscription struct {
33         mutex            sync.Mutex                    // Lock
34         valid            bool                          // valid
35         registry         *Registry                     // Registry
36         ReqId            RequestId                     // ReqId (Requestor Id + Seq Nro a.k.a subsid)
37         Meid             *xapp.RMRMeid                 // Meid/RanName
38         EpList           xapp.RmrEndpointList          // Endpoints
39         RMRRouteCreated  bool                          // Does subscription have RMR route
40         TransLock        sync.Mutex                    // Lock transactions, only one executed per time for subs
41         TheTrans         TransactionIf                 // Ongoing transaction
42         SubReqMsg        *e2ap.E2APSubscriptionRequest // Subscription information
43         SubRFMsg         interface{}                   // Subscription information
44         OngoingReqCount  int                           // Subscription create process is ongoing. In merge case it can ongoing for more than one endpoint
45         OngoingDelCount  int                           // Subscription delete process is ongoing. In merge case it can ongoing for more than one endpoint
46         PolicyUpdate     bool                          // This is true when policy subscrition is being updated. Used not to send delete for update after timeout or restart
47         RetryFromXapp    bool                          // Retry form xApp for subscription that already exist
48         SubRespRcvd      bool                          // Subscription response received
49         DeleteFromDb     bool                          // Delete subscription from db
50         NoRespToXapp     bool                          // Send no response for subscription delete to xApp after restart
51         DoNotWaitSubResp bool                          // Test flag. Response is not waited for Subscription Request
52 }
53
54 func (s *Subscription) String() string {
55         meidstr := "N/A"
56         if s.Meid != nil {
57                 meidstr = s.Meid.String()
58         }
59         return "subs(" + s.ReqId.String() + "/" + meidstr + "/" + s.EpList.String() + ")"
60 }
61
62 func (s *Subscription) GetCachedResponse() (interface{}, bool) {
63         s.mutex.Lock()
64         defer s.mutex.Unlock()
65         return s.SubRFMsg, s.valid
66 }
67
68 func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
69         s.mutex.Lock()
70         defer s.mutex.Unlock()
71         s.SubRFMsg = subRFMsg
72         s.valid = valid
73         return s.SubRFMsg, s.valid
74 }
75
76 func (s *Subscription) GetReqId() *RequestId {
77         s.mutex.Lock()
78         defer s.mutex.Unlock()
79         return &s.ReqId
80 }
81
82 func (s *Subscription) GetMeid() *xapp.RMRMeid {
83         s.mutex.Lock()
84         defer s.mutex.Unlock()
85         return s.Meid
86 }
87
88 func (s *Subscription) GetTransaction() TransactionIf {
89         s.mutex.Lock()
90         defer s.mutex.Unlock()
91         return s.TheTrans
92 }
93
94 func (s *Subscription) WaitTransactionTurn(trans TransactionIf) {
95         s.TransLock.Lock()
96         s.mutex.Lock()
97         s.TheTrans = trans
98         s.mutex.Unlock()
99 }
100
101 func (s *Subscription) ReleaseTransactionTurn(trans TransactionIf) {
102         s.mutex.Lock()
103         if trans != nil && trans == s.TheTrans {
104                 s.TheTrans = nil
105         }
106         s.mutex.Unlock()
107         s.TransLock.Unlock()
108 }
109
110 func (s *Subscription) IsMergeable(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
111         s.mutex.Lock()
112         defer s.mutex.Unlock()
113
114         if s.valid == false {
115                 return false
116         }
117
118         if s.SubReqMsg == nil {
119                 return false
120         }
121
122         if s.Meid.RanName != trans.Meid.RanName {
123                 return false
124         }
125
126         // EventTrigger check
127         if s.SubReqMsg.EventTriggerDefinition.Data.Length != subReqMsg.EventTriggerDefinition.Data.Length {
128                 return false
129         }
130         for i := uint64(0); i < s.SubReqMsg.EventTriggerDefinition.Data.Length; i++ {
131                 if s.SubReqMsg.EventTriggerDefinition.Data.Data[i] != subReqMsg.EventTriggerDefinition.Data.Data[i] {
132                         return false
133                 }
134         }
135
136         // Actions check
137         if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
138                 return false
139         }
140
141         for _, acts := range s.SubReqMsg.ActionSetups {
142                 for _, actt := range subReqMsg.ActionSetups {
143                         if acts.ActionId != actt.ActionId {
144                                 return false
145                         }
146                         if acts.ActionType != actt.ActionType {
147                                 return false
148                         }
149
150                         if acts.ActionType != e2ap.E2AP_ActionTypeReport {
151                                 return false
152                         }
153
154                         if acts.RicActionDefinitionPresent != actt.RicActionDefinitionPresent {
155                                 return false
156                         }
157
158                         if acts.ActionDefinitionChoice.Data.Length != actt.ActionDefinitionChoice.Data.Length {
159                                 return false
160                         }
161                         for i := uint64(0); i < acts.ActionDefinitionChoice.Data.Length; i++ {
162                                 if acts.ActionDefinitionChoice.Data.Data[i] != actt.ActionDefinitionChoice.Data.Data[i] {
163                                         return false
164                                 }
165                         }
166                         if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
167                                 acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
168                                 acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
169                                 return false
170                         }
171                 }
172         }
173         return true
174 }