Merge newe2 into master
[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/submgr/pkg/xapptweaks"
25         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
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    xapptweaks.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 }
45
46 func (s *Subscription) String() string {
47         return "subs(" + s.ReqId.String() + "/" + (&xapptweaks.RMRMeid{s.Meid}).String() + "/" + s.EpList.String() + ")"
48 }
49
50 func (s *Subscription) GetCachedResponse() (interface{}, bool) {
51         s.mutex.Lock()
52         defer s.mutex.Unlock()
53         return s.SubRFMsg, s.valid
54 }
55
56 func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
57         s.mutex.Lock()
58         defer s.mutex.Unlock()
59         s.SubRFMsg = subRFMsg
60         s.valid = valid
61         return s.SubRFMsg, s.valid
62 }
63
64 func (s *Subscription) GetReqId() *RequestId {
65         s.mutex.Lock()
66         defer s.mutex.Unlock()
67         return &s.ReqId
68 }
69
70 func (s *Subscription) GetMeid() *xapp.RMRMeid {
71         s.mutex.Lock()
72         defer s.mutex.Unlock()
73         if s.Meid != nil {
74                 return s.Meid
75         }
76         return nil
77 }
78
79 func (s *Subscription) GetTransaction() TransactionIf {
80         s.mutex.Lock()
81         defer s.mutex.Unlock()
82         return s.TheTrans
83 }
84
85 func (s *Subscription) WaitTransactionTurn(trans TransactionIf) {
86         s.TransLock.Lock()
87         s.mutex.Lock()
88         s.TheTrans = trans
89         s.mutex.Unlock()
90 }
91
92 func (s *Subscription) ReleaseTransactionTurn(trans TransactionIf) {
93         s.mutex.Lock()
94         if trans != nil && trans == s.TheTrans {
95                 s.TheTrans = nil
96         }
97         s.mutex.Unlock()
98         s.TransLock.Unlock()
99 }
100
101 func (s *Subscription) IsMergeable(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
102         s.mutex.Lock()
103         defer s.mutex.Unlock()
104
105         if s.valid == false {
106                 return false
107         }
108
109         if s.SubReqMsg == nil {
110                 return false
111         }
112
113         if s.Meid.RanName != trans.Meid.RanName {
114                 return false
115         }
116
117         // EventTrigger check
118         if s.SubReqMsg.EventTriggerDefinition.InterfaceDirection != subReqMsg.EventTriggerDefinition.InterfaceDirection ||
119                 s.SubReqMsg.EventTriggerDefinition.ProcedureCode != subReqMsg.EventTriggerDefinition.ProcedureCode ||
120                 s.SubReqMsg.EventTriggerDefinition.TypeOfMessage != subReqMsg.EventTriggerDefinition.TypeOfMessage {
121                 return false
122         }
123
124         if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.Present ||
125                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.NodeId ||
126                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.String() != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalEnbId.PlmnIdentity.String() {
127                 return false
128         }
129
130         if s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.Present ||
131                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.NodeId ||
132                 s.SubReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.String() != subReqMsg.EventTriggerDefinition.InterfaceId.GlobalGnbId.PlmnIdentity.String() {
133                 return false
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                                 reflect.DeepEqual(acts.ActionDefinitionChoice, actt.ActionDefinitionChoice) == false {
156                                 return false
157                         }
158
159                         if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
160                                 acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
161                                 acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
162                                 return false
163                         }
164                 }
165         }
166
167         return true
168 }