blob: 8c795406aa4d1935581f6c71845817c8b0b156a3 [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 {
39 xAppRmrEndPoint string
40 Meid string
41 InstanceIds []uint32
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000042 xAppIdToE2Id map[int64]int64
archaggeafbf95f2021-04-14 08:54:05 +030043 SubReqOngoing bool
44 SubDelReqOngoing bool
Markku Virtanen42723e22021-06-15 10:09:23 +030045 lastReqMd5sum string
archaggeafbf95f2021-04-14 08:54:05 +030046}
47
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000048func (r *RESTSubscription) AddE2InstanceId(instanceId uint32) {
Markku Virtanen42723e22021-06-15 10:09:23 +030049
50 for _, v := range r.InstanceIds {
51 if v == instanceId {
52 return
53 }
54
55 }
56
archaggeafbf95f2021-04-14 08:54:05 +030057 r.InstanceIds = append(r.InstanceIds, instanceId)
58}
59
Markku Virtanen42723e22021-06-15 10:09:23 +030060func (r *RESTSubscription) AddMd5Sum(md5sum string) {
61 if md5sum != "" {
62 r.lastReqMd5sum = md5sum
63 } else {
64 xapp.Logger.Error("EMPTY md5sum attempted to be add to subscrition")
65 }
66}
67
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +000068func (r *RESTSubscription) DeleteE2InstanceId(instanceId uint32) {
69 r.InstanceIds = r.InstanceIds[1:]
70}
71
72func (r *RESTSubscription) AddXappIdToE2Id(xAppEventInstanceID int64, e2EventInstanceID int64) {
73 r.xAppIdToE2Id[xAppEventInstanceID] = e2EventInstanceID
74}
75
76func (r *RESTSubscription) GetE2IdFromXappIdToE2Id(xAppEventInstanceID int64) int64 {
77 return r.xAppIdToE2Id[xAppEventInstanceID]
78}
79
80func (r *RESTSubscription) DeleteXappIdToE2Id(xAppEventInstanceID int64) {
81 delete(r.xAppIdToE2Id, xAppEventInstanceID)
82}
83
Markku Virtanen42723e22021-06-15 10:09:23 +030084func (r *RESTSubscription) SetProcessed(err error) {
archaggeafbf95f2021-04-14 08:54:05 +030085 r.SubReqOngoing = false
Markku Virtanen42723e22021-06-15 10:09:23 +030086 if err != nil {
87 r.lastReqMd5sum = ""
88 }
archaggeafbf95f2021-04-14 08:54:05 +030089}
90
kalnagy45114752019-06-18 14:40:39 +020091type Registry struct {
archaggeafbf95f2021-04-14 08:54:05 +030092 mutex sync.Mutex
93 register map[uint32]*Subscription
94 subIds []uint32
95 rtmgrClient *RtmgrClient
96 restSubscriptions map[string]*RESTSubscription
kalnagy45114752019-06-18 14:40:39 +020097}
98
Anssi Mannila5c161a92020-01-15 15:40:57 +020099func (r *Registry) Initialize() {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200100 r.register = make(map[uint32]*Subscription)
archaggeafbf95f2021-04-14 08:54:05 +0300101 r.restSubscriptions = make(map[string]*RESTSubscription)
102
Juha Hyttinen83ada002020-01-30 10:36:33 +0200103 var i uint32
Anssi Mannilac92b4212020-12-07 14:59:34 +0200104 for i = 1; i < 65535; i++ {
105 r.subIds = append(r.subIds, i)
Anssi Mannila5c161a92020-01-15 15:40:57 +0200106 }
kalnagy45114752019-06-18 14:40:39 +0200107}
108
Anssi Mannilab73e7cd2021-08-03 11:57:11 +0300109func (r *Registry) GetAllRestSubscriptions() []byte {
110 r.mutex.Lock()
111 defer r.mutex.Unlock()
112 restSubscriptionsJson, err := json.Marshal(r.restSubscriptions)
113 if err != nil {
114 xapp.Logger.Error("GetAllRestSubscriptions(): %v", err)
115 }
116 return restSubscriptionsJson
117}
118
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300119func (r *Registry) CreateRESTSubscription(restSubId *string, xAppRmrEndPoint *string, maid *string) *RESTSubscription {
archaggeafbf95f2021-04-14 08:54:05 +0300120 r.mutex.Lock()
121 defer r.mutex.Unlock()
122 newRestSubscription := RESTSubscription{}
123 newRestSubscription.xAppRmrEndPoint = *xAppRmrEndPoint
124 newRestSubscription.Meid = *maid
125 newRestSubscription.SubReqOngoing = true
126 newRestSubscription.SubDelReqOngoing = false
127 r.restSubscriptions[*restSubId] = &newRestSubscription
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000128 newRestSubscription.xAppIdToE2Id = make(map[int64]int64)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300129 xapp.Logger.Debug("Registry: Created REST subscription successfully. restSubId=%v, subscriptionCount=%v, e2apSubscriptionCount=%v", *restSubId, len(r.restSubscriptions), len(r.register))
130 return &newRestSubscription
archaggeafbf95f2021-04-14 08:54:05 +0300131}
132
133func (r *Registry) DeleteRESTSubscription(restSubId *string) {
134 r.mutex.Lock()
135 defer r.mutex.Unlock()
136 delete(r.restSubscriptions, *restSubId)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300137 xapp.Logger.Debug("Registry: Deleted REST subscription successfully. restSubId=%v, subscriptionCount=%v", *restSubId, len(r.restSubscriptions))
archaggeafbf95f2021-04-14 08:54:05 +0300138}
139
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000140func (r *Registry) GetRESTSubscription(restSubId string, IsDelReqOngoing bool) (*RESTSubscription, error) {
archaggeafbf95f2021-04-14 08:54:05 +0300141 r.mutex.Lock()
142 defer r.mutex.Unlock()
143 if restSubscription, ok := r.restSubscriptions[restSubId]; ok {
144 // Subscription deletion is not allowed if prosessing subscription request in not ready
145 if restSubscription.SubDelReqOngoing == false && restSubscription.SubReqOngoing == false {
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000146 if IsDelReqOngoing == true {
147 restSubscription.SubDelReqOngoing = true
148 }
archaggeafbf95f2021-04-14 08:54:05 +0300149 r.restSubscriptions[restSubId] = restSubscription
150 return restSubscription, nil
151 } else {
Markku Virtanenda34eec2021-05-20 08:22:04 +0000152 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 +0300153 }
archaggeafbf95f2021-04-14 08:54:05 +0300154 }
155 return nil, fmt.Errorf("Registry: No valid subscription found with restSubId=%v", restSubId)
156}
157
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200158func (r *Registry) QueryHandler() (models.SubscriptionList, error) {
159 r.mutex.Lock()
160 defer r.mutex.Unlock()
161
162 resp := models.SubscriptionList{}
163 for _, subs := range r.register {
164 subs.mutex.Lock()
archaggea5c58bc2021-04-14 08:54:05 +0300165 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 +0200166 subs.mutex.Unlock()
167 }
168 return resp, nil
169}
170
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300171func (r *Registry) allocateSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, rmrRoutecreated bool) (*Subscription, error) {
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200172 if len(r.subIds) > 0 {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300173 subId := r.subIds[0]
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200174 r.subIds = r.subIds[1:]
Juha Hyttinenaada6452020-04-07 08:47:58 +0300175 if _, ok := r.register[subId]; ok == true {
176 r.subIds = append(r.subIds, subId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200177 return nil, fmt.Errorf("Registry: Failed to reserve subscription exists")
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200178 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200179 subs := &Subscription{
Anssi Mannilac92b4212020-12-07 14:59:34 +0200180 registry: r,
181 Meid: trans.Meid,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300182 RMRRouteCreated: rmrRoutecreated,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200183 SubReqMsg: subReqMsg,
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300184 OngoingReqCount: 0,
185 OngoingDelCount: 0,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200186 valid: true,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300187 PolicyUpdate: false,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200188 RetryFromXapp: false,
189 SubRespRcvd: false,
190 DeleteFromDb: false,
191 NoRespToXapp: false,
192 DoNotWaitSubResp: false,
Juha Hyttinen3944a222020-01-24 11:51:46 +0200193 }
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000194 subs.ReqId.Id = subReqMsg.RequestId.Id
Juha Hyttinenaada6452020-04-07 08:47:58 +0300195 subs.ReqId.InstanceId = subId
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300196 r.SetResetTestFlag(resetTestFlag, subs)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200197
198 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300199 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200200 return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
201 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200202 return subs, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200203 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200204 return nil, fmt.Errorf("Registry: Failed to reserve subscription no free ids")
205}
206
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200207func (r *Registry) findExistingSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, bool) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200208
Juha Hyttinen3944a222020-01-24 11:51:46 +0200209 for _, subs := range r.register {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200210 if subs.IsMergeable(trans, subReqMsg) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200211
212 //
213 // check if there has been race conditions
214 //
215 subs.mutex.Lock()
216 //subs has been set to invalid
217 if subs.valid == false {
218 subs.mutex.Unlock()
219 continue
220 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200221 // If size is zero, entry is to be deleted
222 if subs.EpList.Size() == 0 {
223 subs.mutex.Unlock()
224 continue
225 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200226 // Try to add to endpointlist. Adding fails if endpoint is already in the list
Juha Hyttinen3944a222020-01-24 11:51:46 +0200227 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
228 subs.mutex.Unlock()
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200229 xapp.Logger.Debug("Registry: Subs with requesting endpoint found. %s for %s", subs.String(), trans.String())
230 return subs, true
Juha Hyttinen3944a222020-01-24 11:51:46 +0200231 }
232 subs.mutex.Unlock()
233
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200234 xapp.Logger.Debug("Registry: Mergeable subs found. %s for %s", subs.String(), trans.String())
235 return subs, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200236 }
237 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200238 return nil, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200239}
240
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300241func (r *Registry) AssignToSubscription(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, c *Control, createRMRRoute bool) (*Subscription, ErrorInfo, error) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200242 var err error
243 var newAlloc bool
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300244 errorInfo := ErrorInfo{}
Juha Hyttinen3944a222020-01-24 11:51:46 +0200245 r.mutex.Lock()
246 defer r.mutex.Unlock()
247
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200248 //
249 // Check validity of subscription action types
250 //
251 actionType, err := r.CheckActionTypes(subReqMsg)
252 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300253 xapp.Logger.Debug("CREATE %s", err)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300254 err = fmt.Errorf("E2 content validation failed")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300255 return nil, errorInfo, err
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200256 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200257
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200258 //
259 // Find possible existing Policy subscription
260 //
261 if actionType == e2ap.E2AP_ActionTypePolicy {
Juha Hyttinen47942b42020-02-27 10:41:43 +0200262 if subs, ok := r.register[trans.GetSubId()]; ok {
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200263 xapp.Logger.Debug("CREATE %s. Existing subscription for Policy found.", subs.String())
Anssi Mannilacc7d9e02020-04-08 12:58:53 +0300264 // Update message data to subscription
265 subs.SubReqMsg = subReqMsg
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300266 subs.PolicyUpdate = true
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200267 subs.SetCachedResponse(nil, true)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300268 r.SetResetTestFlag(resetTestFlag, subs)
269 return subs, errorInfo, nil
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200270 }
271 }
272
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200273 subs, endPointFound := r.findExistingSubs(trans, subReqMsg)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200274 if subs == nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300275 if subs, err = r.allocateSubs(trans, subReqMsg, resetTestFlag, createRMRRoute); err != nil {
Markku Virtanen55d2a282021-06-04 14:46:56 +0300276 xapp.Logger.Error("%s", err.Error())
277 err = fmt.Errorf("subscription not allocated")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300278 return nil, errorInfo, err
Juha Hyttinen3944a222020-01-24 11:51:46 +0200279 }
280 newAlloc = true
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200281 } else if endPointFound == true {
282 // Requesting endpoint is already present in existing subscription. This can happen if xApp is restarted.
Anssi Mannilac92b4212020-12-07 14:59:34 +0200283 subs.RetryFromXapp = true
Anssi Mannila316d8a12021-06-02 11:08:54 +0300284 xapp.Logger.Debug("CREATE subReqMsg.InstanceId=%v. Same subscription %s already exists.", subReqMsg.InstanceId, subs.String())
285 c.UpdateCounter(cDuplicateE2SubReq)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300286 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200287 }
288
289 //
290 // Add to subscription
291 //
292 subs.mutex.Lock()
293 defer subs.mutex.Unlock()
294
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200295 epamount := subs.EpList.Size()
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300296 xapp.Logger.Debug("AssignToSubscription subs.EpList.Size()=%v", subs.EpList.Size())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200297
298 r.mutex.Unlock()
299 //
300 // Subscription route updates
301 //
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300302 if createRMRRoute == true {
303 if epamount == 1 {
304 errorInfo, err = r.RouteCreate(subs, c)
305 } else {
306 errorInfo, err = r.RouteCreateUpdate(subs, c)
307 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200308 } else {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300309 xapp.Logger.Debug("RMR route not created: createRMRRoute=%v", createRMRRoute)
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200310 }
311 r.mutex.Lock()
312
313 if err != nil {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200314 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300315 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200316 }
Anssi Mannila4abf1802021-01-28 13:06:46 +0200317 // Delete already added endpoint for the request
318 subs.EpList.DelEndpoint(trans.GetEndpoint())
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300319 return nil, errorInfo, err
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200320 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200321
Juha Hyttinen3944a222020-01-24 11:51:46 +0200322 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300323 r.register[subs.ReqId.InstanceId] = subs
Juha Hyttinen3944a222020-01-24 11:51:46 +0200324 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200325 xapp.Logger.Debug("CREATE %s", subs.String())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200326 xapp.Logger.Debug("Registry: substable=%v", r.register)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300327 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200328}
329
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300330func (r *Registry) RouteCreate(subs *Subscription, c *Control) (ErrorInfo, error) {
331 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200332 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
333 err := r.rtmgrClient.SubscriptionRequestCreate(subRouteAction)
334 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300335 if strings.Contains(err.Error(), "status 400") {
336 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
337 } else {
338 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
339 }
340 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200341 c.UpdateCounter(cRouteCreateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300342 xapp.Logger.Error("%s", err.Error())
343 err = fmt.Errorf("RTMGR route create failure")
Anssi Mannila4abf1802021-01-28 13:06:46 +0200344 }
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300345 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200346}
347
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300348func (r *Registry) RouteCreateUpdate(subs *Subscription, c *Control) (ErrorInfo, error) {
349 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200350 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
351 err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
352 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300353 if strings.Contains(err.Error(), "status 400") {
354 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
355 } else {
356 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
357 }
358 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200359 c.UpdateCounter(cRouteCreateUpdateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300360 xapp.Logger.Error("%s", err.Error())
361 err = fmt.Errorf("RTMGR route update failure")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300362 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200363 }
364 c.UpdateCounter(cMergedSubscriptions)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300365 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200366}
367
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200368func (r *Registry) CheckActionTypes(subReqMsg *e2ap.E2APSubscriptionRequest) (uint64, error) {
369 var reportFound bool = false
370 var policyFound bool = false
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300371 var insertFound bool = false
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200372
373 for _, acts := range subReqMsg.ActionSetups {
374 if acts.ActionType == e2ap.E2AP_ActionTypeReport {
375 reportFound = true
376 }
377 if acts.ActionType == e2ap.E2AP_ActionTypePolicy {
378 policyFound = true
379 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300380 if acts.ActionType == e2ap.E2AP_ActionTypeInsert {
381 insertFound = true
382 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200383 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300384 if reportFound == true && policyFound == true || reportFound == true && insertFound == true || policyFound == true && insertFound == true {
385 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 +0200386 }
387 if reportFound == true {
388 return e2ap.E2AP_ActionTypeReport, nil
389 }
390 if policyFound == true {
391 return e2ap.E2AP_ActionTypePolicy, nil
392 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300393 if insertFound == true {
394 return e2ap.E2AP_ActionTypeInsert, nil
395 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200396 return e2ap.E2AP_ActionTypeInvalid, fmt.Errorf("Invalid action type in RICactions-ToBeSetup-List")
397}
398
Juha Hyttinen83ada002020-01-30 10:36:33 +0200399// TODO: Works with concurrent calls, but check if can be improved
Anssi Mannilac92b4212020-12-07 14:59:34 +0200400func (r *Registry) RemoveFromSubscription(subs *Subscription, trans *TransactionXapp, waitRouteClean time.Duration, c *Control) error {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200401
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200402 r.mutex.Lock()
403 defer r.mutex.Unlock()
404 subs.mutex.Lock()
405 defer subs.mutex.Unlock()
406
407 delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint())
408 epamount := subs.EpList.Size()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300409 subId := subs.ReqId.InstanceId
Juha Hyttinen83ada002020-01-30 10:36:33 +0200410 if delStatus == false {
411 return nil
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200412 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200413
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200414 go func() {
415 if waitRouteClean > 0 {
Markku Virtanenfe2cdab2021-05-21 10:59:29 +0000416 xapp.Logger.Debug("Pending %v in order to wait route cleanup", waitRouteClean)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200417 time.Sleep(waitRouteClean)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200418 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200419
420 subs.mutex.Lock()
421 defer subs.mutex.Unlock()
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300422 xapp.Logger.Debug("CLEAN %s", subs.String())
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200423
424 if epamount == 0 {
425 //
426 // Subscription route delete
427 //
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300428 if subs.RMRRouteCreated == true {
429 r.RouteDelete(subs, trans, c)
430 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200431
432 //
433 // Subscription release
434 //
435 r.mutex.Lock()
436 defer r.mutex.Unlock()
437
Juha Hyttinenaada6452020-04-07 08:47:58 +0300438 if _, ok := r.register[subId]; ok {
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200439 xapp.Logger.Debug("RELEASE %s", subs.String())
Juha Hyttinenaada6452020-04-07 08:47:58 +0300440 delete(r.register, subId)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200441 xapp.Logger.Debug("Registry: substable=%v", r.register)
442 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300443 r.subIds = append(r.subIds, subId)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200444 } else if subs.EpList.Size() > 0 {
445 //
Anssi Mannila4abf1802021-01-28 13:06:46 +0200446 // Subscription route update
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200447 //
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300448 if subs.RMRRouteCreated == true {
449 r.RouteDeleteUpdate(subs, c)
450 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200451 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200452 }()
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200453
454 return nil
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200455}
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200456
Anssi Mannila4abf1802021-01-28 13:06:46 +0200457func (r *Registry) RouteDelete(subs *Subscription, trans *TransactionXapp, c *Control) {
458 tmpList := xapp.RmrEndpointList{}
459 tmpList.AddEndpoint(trans.GetEndpoint())
460 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
461 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
462 c.UpdateCounter(cRouteDeleteFail)
463 }
464}
465
466func (r *Registry) RouteDeleteUpdate(subs *Subscription, c *Control) {
467 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
468 if err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction); err != nil {
469 c.UpdateCounter(cRouteDeleteUpdateFail)
470 }
471}
472
Anssi Mannilac92b4212020-12-07 14:59:34 +0200473func (r *Registry) UpdateSubscriptionToDb(subs *Subscription, c *Control) {
474 r.mutex.Lock()
475 defer r.mutex.Unlock()
476 subs.mutex.Lock()
477 defer subs.mutex.Unlock()
478
479 epamount := subs.EpList.Size()
480 if epamount == 0 {
481 if _, ok := r.register[subs.ReqId.InstanceId]; ok {
482 // Not merged subscription is being deleted
483 c.RemoveSubscriptionFromDb(subs)
484
485 }
486 } else if subs.EpList.Size() > 0 {
487 // Endpoint of merged subscription is being deleted
488 c.WriteSubscriptionToDb(subs)
Anssi Mannila4abf1802021-01-28 13:06:46 +0200489 c.UpdateCounter(cUnmergedSubscriptions)
Anssi Mannilac92b4212020-12-07 14:59:34 +0200490 }
491}
492
Juha Hyttinenaada6452020-04-07 08:47:58 +0300493func (r *Registry) GetSubscription(subId uint32) *Subscription {
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200494 r.mutex.Lock()
495 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300496 if _, ok := r.register[subId]; ok {
497 return r.register[subId]
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200498 }
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200499 return nil
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000500}
501
Juha Hyttinenaada6452020-04-07 08:47:58 +0300502func (r *Registry) GetSubscriptionFirstMatch(subIds []uint32) (*Subscription, error) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200503 r.mutex.Lock()
504 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300505 for _, subId := range subIds {
506 if _, ok := r.register[subId]; ok {
507 return r.register[subId], nil
Juha Hyttinen422d0182020-01-17 13:37:05 +0200508 }
509 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300510 return nil, fmt.Errorf("No valid subscription found with subIds %v", subIds)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200511}
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300512
513func (r *Registry) SetResetTestFlag(resetTestFlag bool, subs *Subscription) {
514 if resetTestFlag == true {
515 // This is used in submgr restart unit tests
516 xapp.Logger.Debug("resetTestFlag == true")
517 subs.DoNotWaitSubResp = true
518 } else {
519 xapp.Logger.Debug("resetTestFlag == false")
520 }
521}
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300522
523func (r *Registry) DeleteAllE2Subscriptions(ranName string, c *Control) {
524
525 xapp.Logger.Debug("Registry: DeleteAllE2Subscriptions()")
526 for subId, subs := range r.register {
527 if subs.Meid.RanName == ranName {
528 if subs.OngoingReqCount != 0 || subs.OngoingDelCount != 0 {
529 // Subscription creation or deletion processes need to be processed gracefully till the end.
530 // Subscription is deleted at end of the process in both cases.
531 xapp.Logger.Debug("Registry: E2 subscription under prosessing ongoing cannot delete it yet. subId=%v, OngoingReqCount=%v, OngoingDelCount=%v", subId, subs.OngoingReqCount, subs.OngoingDelCount)
532 continue
533 } else {
534 // Delete route
535 if subs.RMRRouteCreated == true {
536 for _, ep := range subs.EpList.Endpoints {
537 tmpList := xapp.RmrEndpointList{}
538 tmpList.AddEndpoint(&ep)
539 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
540 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
541 c.UpdateCounter(cRouteDeleteFail)
542 }
543 }
544 }
545 // Delete E2 subscription from registry and db
546 xapp.Logger.Debug("Registry: Subscription delete. subId=%v", subId)
547 delete(r.register, subId)
548 r.subIds = append(r.subIds, subId)
549 c.RemoveSubscriptionFromDb(subs)
550 }
551 }
552 }
553
554 // Delete REST subscription from registry and db
555 for restSubId, restSubs := range r.restSubscriptions {
556 if restSubs.Meid == ranName && restSubs.SubReqOngoing == true || restSubs.SubDelReqOngoing == true {
557 // Subscription creation or deletion processes need to be processed gracefully till the end.
558 // Subscription is deleted at end of the process in both cases.
559 xapp.Logger.Debug("Registry: REST subscription under prosessing ongoing cannot delete it yet. RestSubId=%v, SubReqOngoing=%v, SubDelReqOngoing=%v", restSubId, restSubs.SubReqOngoing, restSubs.SubDelReqOngoing)
560 continue
561 } else {
562 xapp.Logger.Debug("Registry: REST subscription delete. subId=%v", restSubId)
563 delete(r.restSubscriptions, restSubId)
564 c.RemoveRESTSubscriptionFromDb(restSubId)
565 }
566 }
567}