blob: 6abdcdb63afc46b223e5206e371f0e97706e3034 [file] [log] [blame]
kalnagy45114752019-06-18 14:40:39 +02001/*
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
20package control
21
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020022import (
Juha Hyttinen0388dd92020-01-09 14:14:16 +020023 "fmt"
Juha Hyttinen422d0182020-01-17 13:37:05 +020024 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020025 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
26 "sync"
Juha Hyttinen12d31af2020-01-22 12:59:01 +020027 "time"
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020028)
29
Juha Hyttinen0d064ec2020-01-09 09:08:53 +020030//-----------------------------------------------------------------------------
31//
32//-----------------------------------------------------------------------------
kalnagy45114752019-06-18 14:40:39 +020033type Registry struct {
Juha Hyttinen0388dd92020-01-09 14:14:16 +020034 mutex sync.Mutex
35 register map[uint16]*Subscription
Anssi Mannila5c161a92020-01-15 15:40:57 +020036 subIds []uint16
Juha Hyttinen0388dd92020-01-09 14:14:16 +020037 rtmgrClient *RtmgrClient
kalnagy45114752019-06-18 14:40:39 +020038}
39
Anssi Mannila5c161a92020-01-15 15:40:57 +020040func (r *Registry) Initialize() {
Juha Hyttinenbf2f4122020-01-02 14:11:02 +020041 r.register = make(map[uint16]*Subscription)
Anssi Mannila5c161a92020-01-15 15:40:57 +020042 var i uint16
43 for i = 0; i < 65535; i++ {
44 r.subIds = append(r.subIds, i+1)
45 }
kalnagy45114752019-06-18 14:40:39 +020046}
47
Juha Hyttinen3944a222020-01-24 11:51:46 +020048func (r *Registry) allocateSubs(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, error) {
Juha Hyttinen12d31af2020-01-22 12:59:01 +020049 if len(r.subIds) > 0 {
Juha Hyttinen3944a222020-01-24 11:51:46 +020050 sequenceNumber := r.subIds[0]
Juha Hyttinen12d31af2020-01-22 12:59:01 +020051 r.subIds = r.subIds[1:]
52 if _, ok := r.register[sequenceNumber]; ok == true {
53 r.subIds = append(r.subIds, sequenceNumber)
Juha Hyttinen3944a222020-01-24 11:51:46 +020054 return nil, fmt.Errorf("Registry: Failed to reserve subscription exists")
Juha Hyttinen12d31af2020-01-22 12:59:01 +020055 }
Juha Hyttinen3944a222020-01-24 11:51:46 +020056 subs := &Subscription{
57 registry: r,
58 Seq: sequenceNumber,
59 Meid: trans.Meid,
60 SubReqMsg: subReqMsg,
61 valid: true,
62 }
63
64 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
65 r.subIds = append(r.subIds, subs.Seq)
66 return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
67 }
68
69 return subs, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +020070 }
Juha Hyttinen3944a222020-01-24 11:51:46 +020071 return nil, fmt.Errorf("Registry: Failed to reserve subscription no free ids")
72}
73
74func (r *Registry) findExistingSubs(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) *Subscription {
75 for _, subs := range r.register {
76 if subs.IsSame(trans, subReqMsg) {
77
78 //
79 // check if there has been race conditions
80 //
81 subs.mutex.Lock()
82 //subs has been set to invalid
83 if subs.valid == false {
84 subs.mutex.Unlock()
85 continue
86 }
87 // try to add to endpointlist.
88 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
89 subs.mutex.Unlock()
90 continue
91 }
92 subs.mutex.Unlock()
93
94 //Race collision during parallel incoming and deleted
95 xapp.Logger.Debug("Registry: Identical subs found %s for %s", subs.String(), trans.String())
96 return subs
97 }
98 }
99 return nil
100}
101
102func (r *Registry) AssignToSubscription(trans *Transaction, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, error) {
103 var err error
104 var newAlloc bool
105 r.mutex.Lock()
106 defer r.mutex.Unlock()
107
108 subs := r.findExistingSubs(trans, subReqMsg)
109
110 if subs == nil {
111 subs, err = r.allocateSubs(trans, subReqMsg)
112 if err != nil {
113 return nil, err
114 }
115 newAlloc = true
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200116 }
117
118 //
119 // Add to subscription
120 //
121 subs.mutex.Lock()
122 defer subs.mutex.Unlock()
123
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200124 epamount := subs.EpList.Size()
125
126 r.mutex.Unlock()
127 //
128 // Subscription route updates
129 //
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200130 if epamount == 1 {
131 subRouteAction := SubRouteInfo{CREATE, subs.EpList, subs.Seq}
132 err = r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
133 } else {
134 subRouteAction := SubRouteInfo{UPDATE, subs.EpList, subs.Seq}
135 err = r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
136 }
137 r.mutex.Lock()
138
139 if err != nil {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200140 if newAlloc {
141 r.subIds = append(r.subIds, subs.Seq)
142 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200143 return nil, err
144 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200145
Juha Hyttinen3944a222020-01-24 11:51:46 +0200146 if newAlloc {
147 r.register[subs.Seq] = subs
148 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200149 xapp.Logger.Debug("Registry: Create %s", subs.String())
150 xapp.Logger.Debug("Registry: substable=%v", r.register)
151 return subs, nil
152}
153
Juha Hyttinen3944a222020-01-24 11:51:46 +0200154// TODO: Needs better logic when there is concurrent calls
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200155func (r *Registry) RemoveFromSubscription(subs *Subscription, trans *Transaction, waitRouteClean time.Duration) error {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200156
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200157 r.mutex.Lock()
158 defer r.mutex.Unlock()
159 subs.mutex.Lock()
160 defer subs.mutex.Unlock()
161
162 delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint())
163 epamount := subs.EpList.Size()
164
165 //
166 // If last endpoint remove from register map
167 //
168 if epamount == 0 {
169 if _, ok := r.register[subs.Seq]; ok {
170 xapp.Logger.Debug("Registry: Delete %s", subs.String())
171 delete(r.register, subs.Seq)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200172 xapp.Logger.Debug("Registry: substable=%v", r.register)
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200173 }
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200174 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200175 r.mutex.Unlock()
176
177 //
178 // Wait some time before really do route updates
179 //
180 if waitRouteClean > 0 {
181 subs.mutex.Unlock()
182 time.Sleep(waitRouteClean)
183 subs.mutex.Lock()
184 }
185
186 xapp.Logger.Info("Registry: Cleaning %s", subs.String())
187
188 //
189 // Subscription route updates
190 //
191 if delStatus {
192 if epamount == 0 {
193 tmpList := RmrEndpointList{}
194 tmpList.AddEndpoint(trans.GetEndpoint())
195 subRouteAction := SubRouteInfo{DELETE, tmpList, subs.Seq}
196 r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
197 } else {
198 subRouteAction := SubRouteInfo{UPDATE, subs.EpList, subs.Seq}
199 r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
200 }
201 }
202
203 r.mutex.Lock()
204 //
205 // If last endpoint free seq nro
206 //
207 if epamount == 0 {
208 r.subIds = append(r.subIds, subs.Seq)
209 }
210
211 return nil
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200212}
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200213
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200214func (r *Registry) GetSubscription(sn uint16) *Subscription {
215 r.mutex.Lock()
216 defer r.mutex.Unlock()
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200217 if _, ok := r.register[sn]; ok {
218 return r.register[sn]
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200219 }
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200220 return nil
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000221}
222
Juha Hyttinen422d0182020-01-17 13:37:05 +0200223func (r *Registry) GetSubscriptionFirstMatch(ids []uint16) (*Subscription, error) {
224 r.mutex.Lock()
225 defer r.mutex.Unlock()
226 for _, id := range ids {
227 if _, ok := r.register[id]; ok {
228 return r.register[id], nil
229 }
230 }
231 return nil, fmt.Errorf("No valid subscription found with ids %v", ids)
232}