blob: 5e9d63e900ce5a839bfa86df1bfa966403434526 [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 (
Anssi Mannilab73e7cd2021-08-03 11:57:11 +030023 "encoding/json"
Juha Hyttinen0388dd92020-01-09 14:14:16 +020024 "fmt"
Anssi Mannilaf682ace2021-09-28 13:11:25 +030025 "strings"
archaggeafbf95f2021-04-14 08:54:05 +030026 "sync"
27 "time"
28
Juha Hyttinen422d0182020-01-17 13:37:05 +020029 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +020030 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020031 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020032)
33
Juha Hyttinen0d064ec2020-01-09 09:08:53 +020034//-----------------------------------------------------------------------------
35//
36//-----------------------------------------------------------------------------
Juha Hyttinen83ada002020-01-30 10:36:33 +020037
archaggeafbf95f2021-04-14 08:54:05 +030038type RESTSubscription struct {
Anssi Mannilad13ba632022-01-04 14:22:26 +020039 Created string
Anssi Mannila92c38552021-12-29 09:59:24 +020040 xAppServiceName string
archaggeafbf95f2021-04-14 08:54:05 +030041 xAppRmrEndPoint string
42 Meid string
43 InstanceIds []uint32
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000044 xAppIdToE2Id map[int64]int64
archaggeafbf95f2021-04-14 08:54:05 +030045 SubReqOngoing bool
46 SubDelReqOngoing bool
Markku Virtanen42723e22021-06-15 10:09:23 +030047 lastReqMd5sum string
archaggeafbf95f2021-04-14 08:54:05 +030048}
49
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000050func (r *RESTSubscription) AddE2InstanceId(instanceId uint32) {
Markku Virtanen42723e22021-06-15 10:09:23 +030051
52 for _, v := range r.InstanceIds {
53 if v == instanceId {
54 return
55 }
56
57 }
58
archaggeafbf95f2021-04-14 08:54:05 +030059 r.InstanceIds = append(r.InstanceIds, instanceId)
60}
61
Markku Virtanen42723e22021-06-15 10:09:23 +030062func (r *RESTSubscription) AddMd5Sum(md5sum string) {
63 if md5sum != "" {
64 r.lastReqMd5sum = md5sum
65 } else {
66 xapp.Logger.Error("EMPTY md5sum attempted to be add to subscrition")
67 }
68}
69
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000070func (r *RESTSubscription) DeleteE2InstanceId(instanceId uint32) {
71 r.InstanceIds = r.InstanceIds[1:]
72}
73
74func (r *RESTSubscription) AddXappIdToE2Id(xAppEventInstanceID int64, e2EventInstanceID int64) {
75 r.xAppIdToE2Id[xAppEventInstanceID] = e2EventInstanceID
76}
77
78func (r *RESTSubscription) GetE2IdFromXappIdToE2Id(xAppEventInstanceID int64) int64 {
79 return r.xAppIdToE2Id[xAppEventInstanceID]
80}
81
82func (r *RESTSubscription) DeleteXappIdToE2Id(xAppEventInstanceID int64) {
83 delete(r.xAppIdToE2Id, xAppEventInstanceID)
84}
85
Markku Virtanen42723e22021-06-15 10:09:23 +030086func (r *RESTSubscription) SetProcessed(err error) {
archaggeafbf95f2021-04-14 08:54:05 +030087 r.SubReqOngoing = false
Markku Virtanen42723e22021-06-15 10:09:23 +030088 if err != nil {
89 r.lastReqMd5sum = ""
90 }
archaggeafbf95f2021-04-14 08:54:05 +030091}
92
kalnagy45114752019-06-18 14:40:39 +020093type Registry struct {
Anssi Mannila54838ed2021-11-19 11:25:01 +020094 mutex *sync.Mutex
archaggeafbf95f2021-04-14 08:54:05 +030095 register map[uint32]*Subscription
96 subIds []uint32
97 rtmgrClient *RtmgrClient
98 restSubscriptions map[string]*RESTSubscription
kalnagy45114752019-06-18 14:40:39 +020099}
100
Anssi Mannila5c161a92020-01-15 15:40:57 +0200101func (r *Registry) Initialize() {
Anssi Mannila54838ed2021-11-19 11:25:01 +0200102 r.mutex = new(sync.Mutex)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200103 r.register = make(map[uint32]*Subscription)
archaggeafbf95f2021-04-14 08:54:05 +0300104 r.restSubscriptions = make(map[string]*RESTSubscription)
105
Juha Hyttinen83ada002020-01-30 10:36:33 +0200106 var i uint32
Anssi Mannilac92b4212020-12-07 14:59:34 +0200107 for i = 1; i < 65535; i++ {
108 r.subIds = append(r.subIds, i)
Anssi Mannila5c161a92020-01-15 15:40:57 +0200109 }
kalnagy45114752019-06-18 14:40:39 +0200110}
111
Anssi Mannila92c38552021-12-29 09:59:24 +0200112func (r *Registry) GetAllRestSubscriptionsJson() []byte {
113
Anssi Mannilab73e7cd2021-08-03 11:57:11 +0300114 r.mutex.Lock()
115 defer r.mutex.Unlock()
116 restSubscriptionsJson, err := json.Marshal(r.restSubscriptions)
117 if err != nil {
Anssi Mannila92c38552021-12-29 09:59:24 +0200118 xapp.Logger.Error("GetAllRestSubscriptions() json.Marshal error: %v", err)
Anssi Mannilab73e7cd2021-08-03 11:57:11 +0300119 }
120 return restSubscriptionsJson
121}
122
Anssi Mannila92c38552021-12-29 09:59:24 +0200123func (r *Registry) GetAllE2NodeRestSubscriptionsJson(ranName string) []byte {
124
125 restSubscriptions := r.GetAllE2NodeRestSubscriptions(ranName)
126 e2NodeRestSubscriptionsJson, err := json.Marshal(restSubscriptions)
127 if err != nil {
128 xapp.Logger.Error("GetE2NodeRestSubscriptions() json.Marshal error: %v", err)
129 }
130 return e2NodeRestSubscriptionsJson
131}
132
133func (r *Registry) GetAllE2NodeRestSubscriptions(ranName string) map[string]RESTSubscription {
134
135 r.mutex.Lock()
136 defer r.mutex.Unlock()
137 var restSubscriptions map[string]RESTSubscription
138 restSubscriptions = make(map[string]RESTSubscription)
139 for restSubsId, restSubscription := range r.restSubscriptions {
140 if restSubscription.Meid == ranName {
141 restSubscriptions[restSubsId] = *restSubscription
142 }
143 }
144 return restSubscriptions
145}
146
147func (r *Registry) GetAllXappsJson() []byte {
148
149 r.mutex.Lock()
150 var xappList []string
151 var xappsMap map[string]string
152 xappsMap = make(map[string]string)
153 for _, restSubscription := range r.restSubscriptions {
154 _, ok := xappsMap[restSubscription.xAppServiceName]
155 if !ok {
156 xappsMap[restSubscription.xAppServiceName] = restSubscription.xAppServiceName
157 xappList = append(xappList, restSubscription.xAppServiceName)
158 }
159 }
160 r.mutex.Unlock()
161
162 xappsJson, err := json.Marshal(xappList)
163 if err != nil {
164 xapp.Logger.Error("GetXapps() json.Marshal error: %v", err)
165 }
166 return xappsJson
167}
168
169func (r *Registry) GetAllXapps() map[string]string {
170
171 r.mutex.Lock()
172 defer r.mutex.Unlock()
173 var xappsMap map[string]string
174 xappsMap = make(map[string]string)
175 for _, restSubscription := range r.restSubscriptions {
176 _, ok := xappsMap[restSubscription.xAppServiceName]
177 if !ok {
178 xappsMap[restSubscription.xAppServiceName] = restSubscription.xAppServiceName
179 }
180 }
181 return xappsMap
182}
183
184func (r *Registry) GetAllXappRestSubscriptionsJson(xAppServiceName string) []byte {
185
186 xappRestSubscriptions := r.GetAllXappRestSubscriptions(xAppServiceName)
187 xappRestSubscriptionsJson, err := json.Marshal(xappRestSubscriptions)
188 if err != nil {
189 xapp.Logger.Error("GetXappRestSubscriptions() json.Marshal error: %v", err)
190 }
191 return xappRestSubscriptionsJson
192}
193
194func (r *Registry) GetAllXappRestSubscriptions(xAppServiceName string) map[string]RESTSubscription {
195
196 r.mutex.Lock()
197 defer r.mutex.Unlock()
198 var xappRestSubscriptions map[string]RESTSubscription
199 xappRestSubscriptions = make(map[string]RESTSubscription)
200 for restSubsId, xappRestSubscription := range r.restSubscriptions {
201 if xappRestSubscription.xAppServiceName == xAppServiceName {
202 xappRestSubscriptions[restSubsId] = *xappRestSubscription
203 }
204 }
205 return xappRestSubscriptions
206}
207
208func (r *Registry) GetE2SubscriptionsJson(restSubsId string) ([]byte, error) {
209
210 // Get all E2 subscriptions of a REST subscription
211 restSubs, err := r.GetRESTSubscription(restSubsId, false)
212 if err != nil {
213 return nil, err
214 }
215
216 r.mutex.Lock()
217 var e2Subscriptions []Subscription
218 for _, e2SubId := range restSubs.InstanceIds {
219 e2Subscription, ok := r.register[e2SubId]
220 if ok {
221 e2Subscriptions = append(e2Subscriptions, *e2Subscription)
222 }
223 }
224 r.mutex.Unlock()
225 e2SubscriptionsJson, err := json.Marshal(e2Subscriptions)
226 if err != nil {
227 xapp.Logger.Error("GetE2Subscriptions() json.Marshal error: %v", err)
228 }
229 return e2SubscriptionsJson, nil
230}
231
232func (r *Registry) CreateRESTSubscription(restSubId *string, xappServiceName *string, xAppRmrEndPoint *string, maid *string) *RESTSubscription {
archaggeafbf95f2021-04-14 08:54:05 +0300233 r.mutex.Lock()
234 defer r.mutex.Unlock()
235 newRestSubscription := RESTSubscription{}
Anssi Mannilad13ba632022-01-04 14:22:26 +0200236 newRestSubscription.Created = time.Now().Format("2006-01-02 15:04:05.000")
Anssi Mannila92c38552021-12-29 09:59:24 +0200237 newRestSubscription.xAppServiceName = *xappServiceName
archaggeafbf95f2021-04-14 08:54:05 +0300238 newRestSubscription.xAppRmrEndPoint = *xAppRmrEndPoint
239 newRestSubscription.Meid = *maid
240 newRestSubscription.SubReqOngoing = true
241 newRestSubscription.SubDelReqOngoing = false
242 r.restSubscriptions[*restSubId] = &newRestSubscription
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000243 newRestSubscription.xAppIdToE2Id = make(map[int64]int64)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300244 xapp.Logger.Debug("Registry: Created REST subscription successfully. restSubId=%v, subscriptionCount=%v, e2apSubscriptionCount=%v", *restSubId, len(r.restSubscriptions), len(r.register))
245 return &newRestSubscription
archaggeafbf95f2021-04-14 08:54:05 +0300246}
247
248func (r *Registry) DeleteRESTSubscription(restSubId *string) {
249 r.mutex.Lock()
250 defer r.mutex.Unlock()
251 delete(r.restSubscriptions, *restSubId)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300252 xapp.Logger.Debug("Registry: Deleted REST subscription successfully. restSubId=%v, subscriptionCount=%v", *restSubId, len(r.restSubscriptions))
archaggeafbf95f2021-04-14 08:54:05 +0300253}
254
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000255func (r *Registry) GetRESTSubscription(restSubId string, IsDelReqOngoing bool) (*RESTSubscription, error) {
archaggeafbf95f2021-04-14 08:54:05 +0300256 r.mutex.Lock()
257 defer r.mutex.Unlock()
258 if restSubscription, ok := r.restSubscriptions[restSubId]; ok {
259 // Subscription deletion is not allowed if prosessing subscription request in not ready
260 if restSubscription.SubDelReqOngoing == false && restSubscription.SubReqOngoing == false {
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000261 if IsDelReqOngoing == true {
262 restSubscription.SubDelReqOngoing = true
263 }
archaggeafbf95f2021-04-14 08:54:05 +0300264 r.restSubscriptions[restSubId] = restSubscription
265 return restSubscription, nil
266 } else {
Markku Virtanenda34eec2021-05-20 08:22:04 +0000267 return restSubscription, fmt.Errorf("Registry: REST request is still ongoing for the endpoint=%v, restSubId=%v, SubDelReqOngoing=%v, SubReqOngoing=%v", restSubscription, restSubId, restSubscription.SubDelReqOngoing, restSubscription.SubReqOngoing)
archaggeafbf95f2021-04-14 08:54:05 +0300268 }
archaggeafbf95f2021-04-14 08:54:05 +0300269 }
270 return nil, fmt.Errorf("Registry: No valid subscription found with restSubId=%v", restSubId)
271}
272
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200273func (r *Registry) QueryHandler() (models.SubscriptionList, error) {
274 r.mutex.Lock()
275 defer r.mutex.Unlock()
276
277 resp := models.SubscriptionList{}
278 for _, subs := range r.register {
279 subs.mutex.Lock()
archaggea5c58bc2021-04-14 08:54:05 +0300280 resp = append(resp, &models.SubscriptionData{SubscriptionID: int64(subs.ReqId.InstanceId), Meid: subs.Meid.RanName, ClientEndpoint: subs.EpList.StringList()})
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200281 subs.mutex.Unlock()
282 }
283 return resp, nil
284}
285
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300286func (r *Registry) allocateSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, rmrRoutecreated bool) (*Subscription, error) {
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200287 if len(r.subIds) > 0 {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300288 subId := r.subIds[0]
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200289 r.subIds = r.subIds[1:]
Juha Hyttinenaada6452020-04-07 08:47:58 +0300290 if _, ok := r.register[subId]; ok == true {
291 r.subIds = append(r.subIds, subId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200292 return nil, fmt.Errorf("Registry: Failed to reserve subscription exists")
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200293 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200294 subs := &Subscription{
Anssi Mannilac92b4212020-12-07 14:59:34 +0200295 registry: r,
296 Meid: trans.Meid,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300297 RMRRouteCreated: rmrRoutecreated,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200298 SubReqMsg: subReqMsg,
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300299 OngoingReqCount: 0,
300 OngoingDelCount: 0,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200301 valid: true,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300302 PolicyUpdate: false,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200303 RetryFromXapp: false,
304 SubRespRcvd: false,
305 DeleteFromDb: false,
306 NoRespToXapp: false,
307 DoNotWaitSubResp: false,
Juha Hyttinen3944a222020-01-24 11:51:46 +0200308 }
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000309 subs.ReqId.Id = subReqMsg.RequestId.Id
Juha Hyttinenaada6452020-04-07 08:47:58 +0300310 subs.ReqId.InstanceId = subId
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300311 r.SetResetTestFlag(resetTestFlag, subs)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200312
313 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300314 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200315 return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
316 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200317 return subs, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200318 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200319 return nil, fmt.Errorf("Registry: Failed to reserve subscription no free ids")
320}
321
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200322func (r *Registry) findExistingSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, bool) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200323
Juha Hyttinen3944a222020-01-24 11:51:46 +0200324 for _, subs := range r.register {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200325 if subs.IsMergeable(trans, subReqMsg) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200326
327 //
328 // check if there has been race conditions
329 //
330 subs.mutex.Lock()
331 //subs has been set to invalid
332 if subs.valid == false {
333 subs.mutex.Unlock()
334 continue
335 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200336 // If size is zero, entry is to be deleted
337 if subs.EpList.Size() == 0 {
338 subs.mutex.Unlock()
339 continue
340 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200341 // Try to add to endpointlist. Adding fails if endpoint is already in the list
Juha Hyttinen3944a222020-01-24 11:51:46 +0200342 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
343 subs.mutex.Unlock()
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200344 xapp.Logger.Debug("Registry: Subs with requesting endpoint found. %s for %s", subs.String(), trans.String())
345 return subs, true
Juha Hyttinen3944a222020-01-24 11:51:46 +0200346 }
347 subs.mutex.Unlock()
348
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200349 xapp.Logger.Debug("Registry: Mergeable subs found. %s for %s", subs.String(), trans.String())
350 return subs, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200351 }
352 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200353 return nil, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200354}
355
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300356func (r *Registry) AssignToSubscription(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, c *Control, createRMRRoute bool) (*Subscription, ErrorInfo, error) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200357 var err error
358 var newAlloc bool
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300359 errorInfo := ErrorInfo{}
Juha Hyttinen3944a222020-01-24 11:51:46 +0200360 r.mutex.Lock()
361 defer r.mutex.Unlock()
362
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200363 //
364 // Check validity of subscription action types
365 //
366 actionType, err := r.CheckActionTypes(subReqMsg)
367 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300368 xapp.Logger.Debug("CREATE %s", err)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300369 err = fmt.Errorf("E2 content validation failed")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300370 return nil, errorInfo, err
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200371 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200372
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200373 //
374 // Find possible existing Policy subscription
375 //
376 if actionType == e2ap.E2AP_ActionTypePolicy {
Juha Hyttinen47942b42020-02-27 10:41:43 +0200377 if subs, ok := r.register[trans.GetSubId()]; ok {
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200378 xapp.Logger.Debug("CREATE %s. Existing subscription for Policy found.", subs.String())
Anssi Mannilacc7d9e02020-04-08 12:58:53 +0300379 // Update message data to subscription
380 subs.SubReqMsg = subReqMsg
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300381 subs.PolicyUpdate = true
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200382 subs.SetCachedResponse(nil, true)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300383 r.SetResetTestFlag(resetTestFlag, subs)
384 return subs, errorInfo, nil
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200385 }
386 }
387
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200388 subs, endPointFound := r.findExistingSubs(trans, subReqMsg)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200389 if subs == nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300390 if subs, err = r.allocateSubs(trans, subReqMsg, resetTestFlag, createRMRRoute); err != nil {
Markku Virtanen55d2a282021-06-04 14:46:56 +0300391 xapp.Logger.Error("%s", err.Error())
392 err = fmt.Errorf("subscription not allocated")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300393 return nil, errorInfo, err
Juha Hyttinen3944a222020-01-24 11:51:46 +0200394 }
395 newAlloc = true
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200396 } else if endPointFound == true {
397 // Requesting endpoint is already present in existing subscription. This can happen if xApp is restarted.
Anssi Mannilac92b4212020-12-07 14:59:34 +0200398 subs.RetryFromXapp = true
Anssi Mannila316d8a12021-06-02 11:08:54 +0300399 xapp.Logger.Debug("CREATE subReqMsg.InstanceId=%v. Same subscription %s already exists.", subReqMsg.InstanceId, subs.String())
400 c.UpdateCounter(cDuplicateE2SubReq)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300401 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200402 }
403
404 //
405 // Add to subscription
406 //
407 subs.mutex.Lock()
408 defer subs.mutex.Unlock()
409
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200410 epamount := subs.EpList.Size()
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300411 xapp.Logger.Debug("AssignToSubscription subs.EpList.Size()=%v", subs.EpList.Size())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200412
413 r.mutex.Unlock()
414 //
415 // Subscription route updates
416 //
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300417 if createRMRRoute == true {
418 if epamount == 1 {
419 errorInfo, err = r.RouteCreate(subs, c)
420 } else {
421 errorInfo, err = r.RouteCreateUpdate(subs, c)
422 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200423 } else {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300424 xapp.Logger.Debug("RMR route not created: createRMRRoute=%v", createRMRRoute)
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200425 }
426 r.mutex.Lock()
427
428 if err != nil {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200429 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300430 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200431 }
Anssi Mannila4abf1802021-01-28 13:06:46 +0200432 // Delete already added endpoint for the request
433 subs.EpList.DelEndpoint(trans.GetEndpoint())
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300434 return nil, errorInfo, err
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200435 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200436
Juha Hyttinen3944a222020-01-24 11:51:46 +0200437 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300438 r.register[subs.ReqId.InstanceId] = subs
Juha Hyttinen3944a222020-01-24 11:51:46 +0200439 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200440 xapp.Logger.Debug("CREATE %s", subs.String())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200441 xapp.Logger.Debug("Registry: substable=%v", r.register)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300442 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200443}
444
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300445func (r *Registry) RouteCreate(subs *Subscription, c *Control) (ErrorInfo, error) {
446 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200447 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
448 err := r.rtmgrClient.SubscriptionRequestCreate(subRouteAction)
449 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300450 if strings.Contains(err.Error(), "status 400") {
451 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
452 } else {
453 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
454 }
455 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200456 c.UpdateCounter(cRouteCreateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300457 xapp.Logger.Error("%s", err.Error())
458 err = fmt.Errorf("RTMGR route create failure")
Anssi Mannila4abf1802021-01-28 13:06:46 +0200459 }
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300460 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200461}
462
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300463func (r *Registry) RouteCreateUpdate(subs *Subscription, c *Control) (ErrorInfo, error) {
464 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200465 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
466 err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
467 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300468 if strings.Contains(err.Error(), "status 400") {
469 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
470 } else {
471 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
472 }
473 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200474 c.UpdateCounter(cRouteCreateUpdateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300475 xapp.Logger.Error("%s", err.Error())
476 err = fmt.Errorf("RTMGR route update failure")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300477 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200478 }
479 c.UpdateCounter(cMergedSubscriptions)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300480 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200481}
482
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200483func (r *Registry) CheckActionTypes(subReqMsg *e2ap.E2APSubscriptionRequest) (uint64, error) {
484 var reportFound bool = false
485 var policyFound bool = false
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300486 var insertFound bool = false
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200487
488 for _, acts := range subReqMsg.ActionSetups {
489 if acts.ActionType == e2ap.E2AP_ActionTypeReport {
490 reportFound = true
491 }
492 if acts.ActionType == e2ap.E2AP_ActionTypePolicy {
493 policyFound = true
494 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300495 if acts.ActionType == e2ap.E2AP_ActionTypeInsert {
496 insertFound = true
497 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200498 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300499 if reportFound == true && policyFound == true || reportFound == true && insertFound == true || policyFound == true && insertFound == true {
500 return e2ap.E2AP_ActionTypeInvalid, fmt.Errorf("Different action types (Report, Policy or Insert) in same RICactions-ToBeSetup-List")
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200501 }
502 if reportFound == true {
503 return e2ap.E2AP_ActionTypeReport, nil
504 }
505 if policyFound == true {
506 return e2ap.E2AP_ActionTypePolicy, nil
507 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300508 if insertFound == true {
509 return e2ap.E2AP_ActionTypeInsert, nil
510 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200511 return e2ap.E2AP_ActionTypeInvalid, fmt.Errorf("Invalid action type in RICactions-ToBeSetup-List")
512}
513
Anssi Mannila55d6fed2022-08-02 12:41:48 +0300514func (r *Registry) RemoveFromSubscription(subs *Subscription, trans *TransactionXapp, waitRouteClean time.Duration, c *Control) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200515
Anssi Mannila54838ed2021-11-19 11:25:01 +0200516 xapp.Logger.Debug("RemoveFromSubscription %s", idstring(nil, trans, subs, trans))
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200517 r.mutex.Lock()
518 defer r.mutex.Unlock()
519 subs.mutex.Lock()
520 defer subs.mutex.Unlock()
521
522 delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint())
523 epamount := subs.EpList.Size()
Anssi Mannila54838ed2021-11-19 11:25:01 +0200524
Juha Hyttinenaada6452020-04-07 08:47:58 +0300525 subId := subs.ReqId.InstanceId
Juha Hyttinen83ada002020-01-30 10:36:33 +0200526 if delStatus == false {
Anssi Mannila55d6fed2022-08-02 12:41:48 +0300527 return
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200528 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200529
Anssi Mannila54838ed2021-11-19 11:25:01 +0200530 if waitRouteClean > 0 {
531 // Wait here that response is delivered to xApp via RMR before route is cleaned
532 xapp.Logger.Debug("Pending %v in order to wait route cleanup", waitRouteClean)
Anssi Mannila9c4697f2022-07-04 15:51:38 +0300533 r.mutex.Unlock()
Anssi Mannila54838ed2021-11-19 11:25:01 +0200534 time.Sleep(waitRouteClean)
Anssi Mannila9c4697f2022-07-04 15:51:38 +0300535 r.mutex.Lock()
Anssi Mannila54838ed2021-11-19 11:25:01 +0200536 }
537
538 xapp.Logger.Debug("CLEAN %s", subs.String())
539
540 if epamount == 0 {
541 //
542 // Subscription route delete
543 //
544 if subs.RMRRouteCreated == true {
545 r.RouteDelete(subs, trans, c)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200546 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200547
Anssi Mannila54838ed2021-11-19 11:25:01 +0200548 // Not merged subscription is being deleted
549 xapp.Logger.Debug("Subscription route delete RemoveSubscriptionFromDb")
550 c.RemoveSubscriptionFromDb(subs)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200551
Anssi Mannila54838ed2021-11-19 11:25:01 +0200552 //
553 // Subscription release
554 //
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200555
Anssi Mannila54838ed2021-11-19 11:25:01 +0200556 if _, ok := r.register[subId]; ok {
557 xapp.Logger.Debug("RELEASE %s", subs.String())
558 delete(r.register, subId)
559 xapp.Logger.Debug("Registry: substable=%v", r.register)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200560 }
Anssi Mannila54838ed2021-11-19 11:25:01 +0200561 r.subIds = append(r.subIds, subId)
562 } else if subs.EpList.Size() > 0 {
563 //
564 // Subscription route update
565 //
566 if subs.RMRRouteCreated == true {
567 r.RouteDeleteUpdate(subs, c)
568 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200569
Anssi Mannila54838ed2021-11-19 11:25:01 +0200570 // Endpoint of merged subscription is being deleted
571 xapp.Logger.Debug("Subscription route update WriteSubscriptionToDb")
Anssi Mannila9c4697f2022-07-04 15:51:38 +0300572 err := c.WriteSubscriptionToDb(subs)
573 if err != nil {
574 xapp.Logger.Error("tracker.UnTrackTransaction() failed:%s", err.Error())
575 }
Anssi Mannila54838ed2021-11-19 11:25:01 +0200576 c.UpdateCounter(cUnmergedSubscriptions)
577 }
Anssi Mannila55d6fed2022-08-02 12:41:48 +0300578 return
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200579}
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200580
Anssi Mannila4abf1802021-01-28 13:06:46 +0200581func (r *Registry) RouteDelete(subs *Subscription, trans *TransactionXapp, c *Control) {
582 tmpList := xapp.RmrEndpointList{}
583 tmpList.AddEndpoint(trans.GetEndpoint())
584 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
585 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
586 c.UpdateCounter(cRouteDeleteFail)
587 }
588}
589
590func (r *Registry) RouteDeleteUpdate(subs *Subscription, c *Control) {
591 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
592 if err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction); err != nil {
593 c.UpdateCounter(cRouteDeleteUpdateFail)
594 }
595}
596
Juha Hyttinenaada6452020-04-07 08:47:58 +0300597func (r *Registry) GetSubscription(subId uint32) *Subscription {
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200598 r.mutex.Lock()
599 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300600 if _, ok := r.register[subId]; ok {
601 return r.register[subId]
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200602 }
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200603 return nil
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000604}
605
Juha Hyttinenaada6452020-04-07 08:47:58 +0300606func (r *Registry) GetSubscriptionFirstMatch(subIds []uint32) (*Subscription, error) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200607 r.mutex.Lock()
608 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300609 for _, subId := range subIds {
610 if _, ok := r.register[subId]; ok {
611 return r.register[subId], nil
Juha Hyttinen422d0182020-01-17 13:37:05 +0200612 }
613 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300614 return nil, fmt.Errorf("No valid subscription found with subIds %v", subIds)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200615}
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300616
617func (r *Registry) SetResetTestFlag(resetTestFlag bool, subs *Subscription) {
618 if resetTestFlag == true {
619 // This is used in submgr restart unit tests
620 xapp.Logger.Debug("resetTestFlag == true")
621 subs.DoNotWaitSubResp = true
622 } else {
623 xapp.Logger.Debug("resetTestFlag == false")
624 }
625}
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300626
627func (r *Registry) DeleteAllE2Subscriptions(ranName string, c *Control) {
628
629 xapp.Logger.Debug("Registry: DeleteAllE2Subscriptions()")
630 for subId, subs := range r.register {
631 if subs.Meid.RanName == ranName {
632 if subs.OngoingReqCount != 0 || subs.OngoingDelCount != 0 {
633 // Subscription creation or deletion processes need to be processed gracefully till the end.
634 // Subscription is deleted at end of the process in both cases.
635 xapp.Logger.Debug("Registry: E2 subscription under prosessing ongoing cannot delete it yet. subId=%v, OngoingReqCount=%v, OngoingDelCount=%v", subId, subs.OngoingReqCount, subs.OngoingDelCount)
636 continue
637 } else {
638 // Delete route
639 if subs.RMRRouteCreated == true {
640 for _, ep := range subs.EpList.Endpoints {
641 tmpList := xapp.RmrEndpointList{}
642 tmpList.AddEndpoint(&ep)
643 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
644 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
645 c.UpdateCounter(cRouteDeleteFail)
646 }
647 }
648 }
649 // Delete E2 subscription from registry and db
650 xapp.Logger.Debug("Registry: Subscription delete. subId=%v", subId)
651 delete(r.register, subId)
652 r.subIds = append(r.subIds, subId)
653 c.RemoveSubscriptionFromDb(subs)
654 }
655 }
656 }
657
658 // Delete REST subscription from registry and db
659 for restSubId, restSubs := range r.restSubscriptions {
Konstantinos Archangelof3a969732022-07-21 12:05:19 +0300660 if restSubs.Meid == ranName {
661 if restSubs.SubReqOngoing == true || restSubs.SubDelReqOngoing == true {
662 // Subscription creation or deletion processes need to be processed gracefully till the end.
663 // Subscription is deleted at end of the process in both cases.
664 xapp.Logger.Debug("Registry: REST subscription under prosessing ongoing cannot delete it yet. RestSubId=%v, SubReqOngoing=%v, SubDelReqOngoing=%v", restSubId, restSubs.SubReqOngoing, restSubs.SubDelReqOngoing)
665 continue
666 } else {
667 xapp.Logger.Debug("Registry: REST subscription delete. subId=%v", restSubId)
668 delete(r.restSubscriptions, restSubId)
669 c.RemoveRESTSubscriptionFromDb(restSubId)
670 }
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300671 }
672 }
673}