RICPLT-3015 Reusing subscription if same EventTrigger and Action
[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         "strconv"
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         Seq        uint16                         // SubsId
37         Meid       *xapp.RMRMeid                  // Meid/ RanName
38         EpList     RmrEndpointList                // Endpoints
39         TransLock  sync.Mutex                     // Lock transactions, only one executed per time for subs
40         TheTrans   *Transaction                   // Ongoing transaction from xapp
41         SubReqMsg  *e2ap.E2APSubscriptionRequest  // Subscription information
42         SubRespMsg *e2ap.E2APSubscriptionResponse // Subscription information
43         SubFailMsg *e2ap.E2APSubscriptionFailure  // Subscription information
44 }
45
46 func (s *Subscription) String() string {
47         return "subs(" + strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.Meid.RanName + "/" + s.EpList.String() + ")"
48 }
49
50 func (s *Subscription) GetSubId() uint16 {
51         s.mutex.Lock()
52         defer s.mutex.Unlock()
53         return s.Seq
54 }
55
56 func (s *Subscription) GetMeid() *xapp.RMRMeid {
57         s.mutex.Lock()
58         defer s.mutex.Unlock()
59         if s.Meid != nil {
60                 return s.Meid
61         }
62         return nil
63 }
64
65 func (s *Subscription) IsTransactionReserved() bool {
66         s.mutex.Lock()
67         defer s.mutex.Unlock()
68         if s.TheTrans != nil {
69                 return true
70         }
71         return false
72
73 }
74
75 func (s *Subscription) GetTransaction() *Transaction {
76         s.mutex.Lock()
77         defer s.mutex.Unlock()
78         return s.TheTrans
79 }
80
81 func (s *Subscription) WaitTransactionTurn(trans *Transaction) {
82         s.TransLock.Lock()
83         s.mutex.Lock()
84         s.TheTrans = trans
85         s.mutex.Unlock()
86 }
87
88 func (s *Subscription) ReleaseTransactionTurn(trans *Transaction) {
89         s.mutex.Lock()
90         if trans != nil && trans == s.TheTrans {
91                 s.TheTrans = nil
92         }
93         s.mutex.Unlock()
94         s.TransLock.Unlock()
95 }
96
97 func (s *Subscription) IsSame(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
98         s.mutex.Lock()
99         defer s.mutex.Unlock()
100
101         if s.valid == false {
102                 return false
103         }
104
105         if s.SubReqMsg == nil {
106                 return false
107         }
108
109         if s.Meid.RanName != trans.Meid.RanName {
110                 return false
111         }
112
113         if s.EpList.Size() == 0 {
114                 return false
115         }
116
117         //Somehow special case ... ?
118         if s.EpList.HasEndpoint(trans.GetEndpoint()) == true {
119                 return false
120         }
121
122         // EventTrigger check
123         if s.SubReqMsg.EventTriggerDefinition.InterfaceDirection != subReqMsg.EventTriggerDefinition.InterfaceDirection ||
124                 s.SubReqMsg.EventTriggerDefinition.ProcedureCode != subReqMsg.EventTriggerDefinition.ProcedureCode ||
125                 s.SubReqMsg.EventTriggerDefinition.TypeOfMessage != subReqMsg.EventTriggerDefinition.TypeOfMessage {
126                 return false
127         }
128
129         if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present ||
130                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId ||
131                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[0] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[0] ||
132                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[1] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[1] ||
133                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[2] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.Val[2] {
134                 return false
135         }
136
137         if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present ||
138                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId ||
139                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[0] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[0] ||
140                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[1] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[1] ||
141                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[2] != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.Val[2] {
142                 return false
143         }
144
145         // Actions check
146         if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
147                 return false
148         }
149
150         for _, acts := range s.SubReqMsg.ActionSetups {
151                 for _, actt := range subReqMsg.ActionSetups {
152                         if acts.ActionId != actt.ActionId {
153                                 return false
154                         }
155                         if acts.ActionType != actt.ActionType {
156                                 return false
157                         }
158
159                         if acts.ActionDefinition.Present != actt.ActionDefinition.Present ||
160                                 acts.ActionDefinition.StyleId != actt.ActionDefinition.StyleId ||
161                                 acts.ActionDefinition.ParamId != actt.ActionDefinition.ParamId {
162                                 return false
163                         }
164                         if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
165                                 acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
166                                 acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
167                                 return false
168                         }
169                 }
170         }
171
172         return true
173 }