Submgr restart improvement
[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         //"reflect"
27         "sync"
28 )
29
30 //-----------------------------------------------------------------------------
31 //
32 //-----------------------------------------------------------------------------
33 type Subscription struct {
34         mutex            sync.Mutex                    // Lock
35         valid            bool                          // valid
36         registry         *Registry                     // Registry
37         ReqId            RequestId                     // ReqId (Requestor Id + Seq Nro a.k.a subsid)
38         Meid             *xapp.RMRMeid                 // Meid/ RanName
39         EpList           xapp.RmrEndpointList          // Endpoints
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         RetryFromXapp    bool                          // Retry form xApp for subscription that already exist
45         SubRespRcvd      bool                          // Subscription response received
46         DeleteFromDb     bool                          // Delete subscription form db
47         NoRespToXapp     bool                          // Send no response for subscription delete to xApp after restart
48         DoNotWaitSubResp bool                          // Test flag. Response is not waited for Subscription Request
49 }
50
51 func (s *Subscription) String() string {
52         meidstr := "N/A"
53         if s.Meid != nil {
54                 meidstr = s.Meid.String()
55         }
56         return "subs(" + s.ReqId.String() + "/" + meidstr + "/" + s.EpList.String() + ")"
57 }
58
59 func (s *Subscription) GetCachedResponse() (interface{}, bool) {
60         s.mutex.Lock()
61         defer s.mutex.Unlock()
62         return s.SubRFMsg, s.valid
63 }
64
65 func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
66         s.mutex.Lock()
67         defer s.mutex.Unlock()
68         s.SubRFMsg = subRFMsg
69         s.valid = valid
70         return s.SubRFMsg, s.valid
71 }
72
73 func (s *Subscription) GetReqId() *RequestId {
74         s.mutex.Lock()
75         defer s.mutex.Unlock()
76         return &s.ReqId
77 }
78
79 func (s *Subscription) GetMeid() *xapp.RMRMeid {
80         s.mutex.Lock()
81         defer s.mutex.Unlock()
82         if s.Meid != nil {
83                 return s.Meid
84         }
85         return nil
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                         //reflect.DeepEqual(acts.ActionDefinitionChoice, actt.ActionDefinitionChoice)
167
168                         if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
169                                 acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
170                                 acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
171                                 return false
172                         }
173                 }
174         }
175
176         return true
177 }