blob: 36e9b4c9f68b93abd7821ec59a70b04370a172f6 [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 {
Anssi Mannila54838ed2021-11-19 11:25:01 +020092 mutex *sync.Mutex
archaggeafbf95f2021-04-14 08:54:05 +030093 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() {
Anssi Mannila54838ed2021-11-19 11:25:01 +0200100 r.mutex = new(sync.Mutex)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200101 r.register = make(map[uint32]*Subscription)
archaggeafbf95f2021-04-14 08:54:05 +0300102 r.restSubscriptions = make(map[string]*RESTSubscription)
103
Juha Hyttinen83ada002020-01-30 10:36:33 +0200104 var i uint32
Anssi Mannilac92b4212020-12-07 14:59:34 +0200105 for i = 1; i < 65535; i++ {
106 r.subIds = append(r.subIds, i)
Anssi Mannila5c161a92020-01-15 15:40:57 +0200107 }
kalnagy45114752019-06-18 14:40:39 +0200108}
109
Anssi Mannilab73e7cd2021-08-03 11:57:11 +0300110func (r *Registry) GetAllRestSubscriptions() []byte {
111 r.mutex.Lock()
112 defer r.mutex.Unlock()
113 restSubscriptionsJson, err := json.Marshal(r.restSubscriptions)
114 if err != nil {
115 xapp.Logger.Error("GetAllRestSubscriptions(): %v", err)
116 }
117 return restSubscriptionsJson
118}
119
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300120func (r *Registry) CreateRESTSubscription(restSubId *string, xAppRmrEndPoint *string, maid *string) *RESTSubscription {
archaggeafbf95f2021-04-14 08:54:05 +0300121 r.mutex.Lock()
122 defer r.mutex.Unlock()
123 newRestSubscription := RESTSubscription{}
124 newRestSubscription.xAppRmrEndPoint = *xAppRmrEndPoint
125 newRestSubscription.Meid = *maid
126 newRestSubscription.SubReqOngoing = true
127 newRestSubscription.SubDelReqOngoing = false
128 r.restSubscriptions[*restSubId] = &newRestSubscription
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000129 newRestSubscription.xAppIdToE2Id = make(map[int64]int64)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300130 xapp.Logger.Debug("Registry: Created REST subscription successfully. restSubId=%v, subscriptionCount=%v, e2apSubscriptionCount=%v", *restSubId, len(r.restSubscriptions), len(r.register))
131 return &newRestSubscription
archaggeafbf95f2021-04-14 08:54:05 +0300132}
133
134func (r *Registry) DeleteRESTSubscription(restSubId *string) {
135 r.mutex.Lock()
136 defer r.mutex.Unlock()
137 delete(r.restSubscriptions, *restSubId)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300138 xapp.Logger.Debug("Registry: Deleted REST subscription successfully. restSubId=%v, subscriptionCount=%v", *restSubId, len(r.restSubscriptions))
archaggeafbf95f2021-04-14 08:54:05 +0300139}
140
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000141func (r *Registry) GetRESTSubscription(restSubId string, IsDelReqOngoing bool) (*RESTSubscription, error) {
archaggeafbf95f2021-04-14 08:54:05 +0300142 r.mutex.Lock()
143 defer r.mutex.Unlock()
144 if restSubscription, ok := r.restSubscriptions[restSubId]; ok {
145 // Subscription deletion is not allowed if prosessing subscription request in not ready
146 if restSubscription.SubDelReqOngoing == false && restSubscription.SubReqOngoing == false {
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000147 if IsDelReqOngoing == true {
148 restSubscription.SubDelReqOngoing = true
149 }
archaggeafbf95f2021-04-14 08:54:05 +0300150 r.restSubscriptions[restSubId] = restSubscription
151 return restSubscription, nil
152 } else {
Markku Virtanenda34eec2021-05-20 08:22:04 +0000153 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 +0300154 }
archaggeafbf95f2021-04-14 08:54:05 +0300155 }
156 return nil, fmt.Errorf("Registry: No valid subscription found with restSubId=%v", restSubId)
157}
158
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200159func (r *Registry) QueryHandler() (models.SubscriptionList, error) {
160 r.mutex.Lock()
161 defer r.mutex.Unlock()
162
163 resp := models.SubscriptionList{}
164 for _, subs := range r.register {
165 subs.mutex.Lock()
archaggea5c58bc2021-04-14 08:54:05 +0300166 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 +0200167 subs.mutex.Unlock()
168 }
169 return resp, nil
170}
171
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300172func (r *Registry) allocateSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, rmrRoutecreated bool) (*Subscription, error) {
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200173 if len(r.subIds) > 0 {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300174 subId := r.subIds[0]
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200175 r.subIds = r.subIds[1:]
Juha Hyttinenaada6452020-04-07 08:47:58 +0300176 if _, ok := r.register[subId]; ok == true {
177 r.subIds = append(r.subIds, subId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200178 return nil, fmt.Errorf("Registry: Failed to reserve subscription exists")
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200179 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200180 subs := &Subscription{
Anssi Mannilac92b4212020-12-07 14:59:34 +0200181 registry: r,
182 Meid: trans.Meid,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300183 RMRRouteCreated: rmrRoutecreated,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200184 SubReqMsg: subReqMsg,
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300185 OngoingReqCount: 0,
186 OngoingDelCount: 0,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200187 valid: true,
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300188 PolicyUpdate: false,
Anssi Mannilac92b4212020-12-07 14:59:34 +0200189 RetryFromXapp: false,
190 SubRespRcvd: false,
191 DeleteFromDb: false,
192 NoRespToXapp: false,
193 DoNotWaitSubResp: false,
Juha Hyttinen3944a222020-01-24 11:51:46 +0200194 }
Konstantinos Archangelofe93b00f2021-06-03 10:00:19 +0000195 subs.ReqId.Id = subReqMsg.RequestId.Id
Juha Hyttinenaada6452020-04-07 08:47:58 +0300196 subs.ReqId.InstanceId = subId
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300197 r.SetResetTestFlag(resetTestFlag, subs)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200198
199 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300200 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200201 return nil, fmt.Errorf("Registry: Endpoint existing already in subscription")
202 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200203 return subs, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200204 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200205 return nil, fmt.Errorf("Registry: Failed to reserve subscription no free ids")
206}
207
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200208func (r *Registry) findExistingSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) (*Subscription, bool) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200209
Juha Hyttinen3944a222020-01-24 11:51:46 +0200210 for _, subs := range r.register {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200211 if subs.IsMergeable(trans, subReqMsg) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200212
213 //
214 // check if there has been race conditions
215 //
216 subs.mutex.Lock()
217 //subs has been set to invalid
218 if subs.valid == false {
219 subs.mutex.Unlock()
220 continue
221 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200222 // If size is zero, entry is to be deleted
223 if subs.EpList.Size() == 0 {
224 subs.mutex.Unlock()
225 continue
226 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200227 // Try to add to endpointlist. Adding fails if endpoint is already in the list
Juha Hyttinen3944a222020-01-24 11:51:46 +0200228 if subs.EpList.AddEndpoint(trans.GetEndpoint()) == false {
229 subs.mutex.Unlock()
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200230 xapp.Logger.Debug("Registry: Subs with requesting endpoint found. %s for %s", subs.String(), trans.String())
231 return subs, true
Juha Hyttinen3944a222020-01-24 11:51:46 +0200232 }
233 subs.mutex.Unlock()
234
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200235 xapp.Logger.Debug("Registry: Mergeable subs found. %s for %s", subs.String(), trans.String())
236 return subs, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200237 }
238 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200239 return nil, false
Juha Hyttinen3944a222020-01-24 11:51:46 +0200240}
241
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300242func (r *Registry) AssignToSubscription(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, resetTestFlag bool, c *Control, createRMRRoute bool) (*Subscription, ErrorInfo, error) {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200243 var err error
244 var newAlloc bool
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300245 errorInfo := ErrorInfo{}
Juha Hyttinen3944a222020-01-24 11:51:46 +0200246 r.mutex.Lock()
247 defer r.mutex.Unlock()
248
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200249 //
250 // Check validity of subscription action types
251 //
252 actionType, err := r.CheckActionTypes(subReqMsg)
253 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300254 xapp.Logger.Debug("CREATE %s", err)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300255 err = fmt.Errorf("E2 content validation failed")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300256 return nil, errorInfo, err
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200257 }
Juha Hyttinen3944a222020-01-24 11:51:46 +0200258
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200259 //
260 // Find possible existing Policy subscription
261 //
262 if actionType == e2ap.E2AP_ActionTypePolicy {
Juha Hyttinen47942b42020-02-27 10:41:43 +0200263 if subs, ok := r.register[trans.GetSubId()]; ok {
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200264 xapp.Logger.Debug("CREATE %s. Existing subscription for Policy found.", subs.String())
Anssi Mannilacc7d9e02020-04-08 12:58:53 +0300265 // Update message data to subscription
266 subs.SubReqMsg = subReqMsg
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300267 subs.PolicyUpdate = true
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200268 subs.SetCachedResponse(nil, true)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300269 r.SetResetTestFlag(resetTestFlag, subs)
270 return subs, errorInfo, nil
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200271 }
272 }
273
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200274 subs, endPointFound := r.findExistingSubs(trans, subReqMsg)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200275 if subs == nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300276 if subs, err = r.allocateSubs(trans, subReqMsg, resetTestFlag, createRMRRoute); err != nil {
Markku Virtanen55d2a282021-06-04 14:46:56 +0300277 xapp.Logger.Error("%s", err.Error())
278 err = fmt.Errorf("subscription not allocated")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300279 return nil, errorInfo, err
Juha Hyttinen3944a222020-01-24 11:51:46 +0200280 }
281 newAlloc = true
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200282 } else if endPointFound == true {
283 // Requesting endpoint is already present in existing subscription. This can happen if xApp is restarted.
Anssi Mannilac92b4212020-12-07 14:59:34 +0200284 subs.RetryFromXapp = true
Anssi Mannila316d8a12021-06-02 11:08:54 +0300285 xapp.Logger.Debug("CREATE subReqMsg.InstanceId=%v. Same subscription %s already exists.", subReqMsg.InstanceId, subs.String())
286 c.UpdateCounter(cDuplicateE2SubReq)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300287 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200288 }
289
290 //
291 // Add to subscription
292 //
293 subs.mutex.Lock()
294 defer subs.mutex.Unlock()
295
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200296 epamount := subs.EpList.Size()
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300297 xapp.Logger.Debug("AssignToSubscription subs.EpList.Size()=%v", subs.EpList.Size())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200298
299 r.mutex.Unlock()
300 //
301 // Subscription route updates
302 //
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300303 if createRMRRoute == true {
304 if epamount == 1 {
305 errorInfo, err = r.RouteCreate(subs, c)
306 } else {
307 errorInfo, err = r.RouteCreateUpdate(subs, c)
308 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200309 } else {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300310 xapp.Logger.Debug("RMR route not created: createRMRRoute=%v", createRMRRoute)
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200311 }
312 r.mutex.Lock()
313
314 if err != nil {
Juha Hyttinen3944a222020-01-24 11:51:46 +0200315 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300316 r.subIds = append(r.subIds, subs.ReqId.InstanceId)
Juha Hyttinen3944a222020-01-24 11:51:46 +0200317 }
Anssi Mannila4abf1802021-01-28 13:06:46 +0200318 // Delete already added endpoint for the request
319 subs.EpList.DelEndpoint(trans.GetEndpoint())
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300320 return nil, errorInfo, err
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200321 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200322
Juha Hyttinen3944a222020-01-24 11:51:46 +0200323 if newAlloc {
Juha Hyttinenaada6452020-04-07 08:47:58 +0300324 r.register[subs.ReqId.InstanceId] = subs
Juha Hyttinen3944a222020-01-24 11:51:46 +0200325 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200326 xapp.Logger.Debug("CREATE %s", subs.String())
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200327 xapp.Logger.Debug("Registry: substable=%v", r.register)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300328 return subs, errorInfo, nil
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200329}
330
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300331func (r *Registry) RouteCreate(subs *Subscription, c *Control) (ErrorInfo, error) {
332 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200333 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
334 err := r.rtmgrClient.SubscriptionRequestCreate(subRouteAction)
335 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300336 if strings.Contains(err.Error(), "status 400") {
337 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
338 } else {
339 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
340 }
341 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200342 c.UpdateCounter(cRouteCreateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300343 xapp.Logger.Error("%s", err.Error())
344 err = fmt.Errorf("RTMGR route create failure")
Anssi Mannila4abf1802021-01-28 13:06:46 +0200345 }
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300346 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200347}
348
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300349func (r *Registry) RouteCreateUpdate(subs *Subscription, c *Control) (ErrorInfo, error) {
350 errorInfo := ErrorInfo{}
Anssi Mannila4abf1802021-01-28 13:06:46 +0200351 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
352 err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
353 if err != nil {
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300354 if strings.Contains(err.Error(), "status 400") {
355 errorInfo.TimeoutType = models.SubscriptionInstanceTimeoutTypeRTMGRTimeout
356 } else {
357 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceRTMGR
358 }
359 errorInfo.ErrorCause = err.Error()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200360 c.UpdateCounter(cRouteCreateUpdateFail)
Markku Virtanen55d2a282021-06-04 14:46:56 +0300361 xapp.Logger.Error("%s", err.Error())
362 err = fmt.Errorf("RTMGR route update failure")
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300363 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200364 }
365 c.UpdateCounter(cMergedSubscriptions)
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300366 return errorInfo, err
Anssi Mannila4abf1802021-01-28 13:06:46 +0200367}
368
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200369func (r *Registry) CheckActionTypes(subReqMsg *e2ap.E2APSubscriptionRequest) (uint64, error) {
370 var reportFound bool = false
371 var policyFound bool = false
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300372 var insertFound bool = false
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200373
374 for _, acts := range subReqMsg.ActionSetups {
375 if acts.ActionType == e2ap.E2AP_ActionTypeReport {
376 reportFound = true
377 }
378 if acts.ActionType == e2ap.E2AP_ActionTypePolicy {
379 policyFound = true
380 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300381 if acts.ActionType == e2ap.E2AP_ActionTypeInsert {
382 insertFound = true
383 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200384 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300385 if reportFound == true && policyFound == true || reportFound == true && insertFound == true || policyFound == true && insertFound == true {
386 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 +0200387 }
388 if reportFound == true {
389 return e2ap.E2AP_ActionTypeReport, nil
390 }
391 if policyFound == true {
392 return e2ap.E2AP_ActionTypePolicy, nil
393 }
Anssi Mannilaf0d95262020-08-17 13:00:20 +0300394 if insertFound == true {
395 return e2ap.E2AP_ActionTypeInsert, nil
396 }
Anssi Mannila9bcb0a42020-02-11 11:30:44 +0200397 return e2ap.E2AP_ActionTypeInvalid, fmt.Errorf("Invalid action type in RICactions-ToBeSetup-List")
398}
399
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
Anssi Mannila54838ed2021-11-19 11:25:01 +0200402 xapp.Logger.Debug("RemoveFromSubscription %s", idstring(nil, trans, subs, trans))
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200403 r.mutex.Lock()
404 defer r.mutex.Unlock()
405 subs.mutex.Lock()
406 defer subs.mutex.Unlock()
407
408 delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint())
409 epamount := subs.EpList.Size()
Anssi Mannila54838ed2021-11-19 11:25:01 +0200410
Juha Hyttinenaada6452020-04-07 08:47:58 +0300411 subId := subs.ReqId.InstanceId
Juha Hyttinen83ada002020-01-30 10:36:33 +0200412 if delStatus == false {
413 return nil
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200414 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200415
Anssi Mannila54838ed2021-11-19 11:25:01 +0200416 if waitRouteClean > 0 {
417 // Wait here that response is delivered to xApp via RMR before route is cleaned
418 xapp.Logger.Debug("Pending %v in order to wait route cleanup", waitRouteClean)
419 time.Sleep(waitRouteClean)
420 }
421
422 xapp.Logger.Debug("CLEAN %s", subs.String())
423
424 if epamount == 0 {
425 //
426 // Subscription route delete
427 //
428 if subs.RMRRouteCreated == true {
429 r.RouteDelete(subs, trans, c)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200430 }
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200431
Anssi Mannila54838ed2021-11-19 11:25:01 +0200432 // Not merged subscription is being deleted
433 xapp.Logger.Debug("Subscription route delete RemoveSubscriptionFromDb")
434 c.RemoveSubscriptionFromDb(subs)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200435
Anssi Mannila54838ed2021-11-19 11:25:01 +0200436 //
437 // Subscription release
438 //
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200439
Anssi Mannila54838ed2021-11-19 11:25:01 +0200440 if _, ok := r.register[subId]; ok {
441 xapp.Logger.Debug("RELEASE %s", subs.String())
442 delete(r.register, subId)
443 xapp.Logger.Debug("Registry: substable=%v", r.register)
Juha Hyttinenf44377d2020-02-12 10:18:40 +0200444 }
Anssi Mannila54838ed2021-11-19 11:25:01 +0200445 r.subIds = append(r.subIds, subId)
446 } else if subs.EpList.Size() > 0 {
447 //
448 // Subscription route update
449 //
450 if subs.RMRRouteCreated == true {
451 r.RouteDeleteUpdate(subs, c)
452 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200453
Anssi Mannila54838ed2021-11-19 11:25:01 +0200454 // Endpoint of merged subscription is being deleted
455 xapp.Logger.Debug("Subscription route update WriteSubscriptionToDb")
456 c.WriteSubscriptionToDb(subs)
457 c.UpdateCounter(cUnmergedSubscriptions)
458 }
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200459 return nil
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200460}
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200461
Anssi Mannila4abf1802021-01-28 13:06:46 +0200462func (r *Registry) RouteDelete(subs *Subscription, trans *TransactionXapp, c *Control) {
463 tmpList := xapp.RmrEndpointList{}
464 tmpList.AddEndpoint(trans.GetEndpoint())
465 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
466 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
467 c.UpdateCounter(cRouteDeleteFail)
468 }
469}
470
471func (r *Registry) RouteDeleteUpdate(subs *Subscription, c *Control) {
472 subRouteAction := SubRouteInfo{subs.EpList, uint16(subs.ReqId.InstanceId)}
473 if err := r.rtmgrClient.SubscriptionRequestUpdate(subRouteAction); err != nil {
474 c.UpdateCounter(cRouteDeleteUpdateFail)
475 }
476}
477
Juha Hyttinenaada6452020-04-07 08:47:58 +0300478func (r *Registry) GetSubscription(subId uint32) *Subscription {
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200479 r.mutex.Lock()
480 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300481 if _, ok := r.register[subId]; ok {
482 return r.register[subId]
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200483 }
Juha Hyttinen47b842b2020-01-08 13:01:52 +0200484 return nil
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000485}
486
Juha Hyttinenaada6452020-04-07 08:47:58 +0300487func (r *Registry) GetSubscriptionFirstMatch(subIds []uint32) (*Subscription, error) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200488 r.mutex.Lock()
489 defer r.mutex.Unlock()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300490 for _, subId := range subIds {
491 if _, ok := r.register[subId]; ok {
492 return r.register[subId], nil
Juha Hyttinen422d0182020-01-17 13:37:05 +0200493 }
494 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300495 return nil, fmt.Errorf("No valid subscription found with subIds %v", subIds)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200496}
Anssi Mannilaf682ace2021-09-28 13:11:25 +0300497
498func (r *Registry) SetResetTestFlag(resetTestFlag bool, subs *Subscription) {
499 if resetTestFlag == true {
500 // This is used in submgr restart unit tests
501 xapp.Logger.Debug("resetTestFlag == true")
502 subs.DoNotWaitSubResp = true
503 } else {
504 xapp.Logger.Debug("resetTestFlag == false")
505 }
506}
Anssi Mannilac7da4ee2021-10-22 09:52:02 +0300507
508func (r *Registry) DeleteAllE2Subscriptions(ranName string, c *Control) {
509
510 xapp.Logger.Debug("Registry: DeleteAllE2Subscriptions()")
511 for subId, subs := range r.register {
512 if subs.Meid.RanName == ranName {
513 if subs.OngoingReqCount != 0 || subs.OngoingDelCount != 0 {
514 // Subscription creation or deletion processes need to be processed gracefully till the end.
515 // Subscription is deleted at end of the process in both cases.
516 xapp.Logger.Debug("Registry: E2 subscription under prosessing ongoing cannot delete it yet. subId=%v, OngoingReqCount=%v, OngoingDelCount=%v", subId, subs.OngoingReqCount, subs.OngoingDelCount)
517 continue
518 } else {
519 // Delete route
520 if subs.RMRRouteCreated == true {
521 for _, ep := range subs.EpList.Endpoints {
522 tmpList := xapp.RmrEndpointList{}
523 tmpList.AddEndpoint(&ep)
524 subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)}
525 if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil {
526 c.UpdateCounter(cRouteDeleteFail)
527 }
528 }
529 }
530 // Delete E2 subscription from registry and db
531 xapp.Logger.Debug("Registry: Subscription delete. subId=%v", subId)
532 delete(r.register, subId)
533 r.subIds = append(r.subIds, subId)
534 c.RemoveSubscriptionFromDb(subs)
535 }
536 }
537 }
538
539 // Delete REST subscription from registry and db
540 for restSubId, restSubs := range r.restSubscriptions {
541 if restSubs.Meid == ranName && restSubs.SubReqOngoing == true || restSubs.SubDelReqOngoing == true {
542 // Subscription creation or deletion processes need to be processed gracefully till the end.
543 // Subscription is deleted at end of the process in both cases.
544 xapp.Logger.Debug("Registry: REST subscription under prosessing ongoing cannot delete it yet. RestSubId=%v, SubReqOngoing=%v, SubDelReqOngoing=%v", restSubId, restSubs.SubReqOngoing, restSubs.SubDelReqOngoing)
545 continue
546 } else {
547 xapp.Logger.Debug("Registry: REST subscription delete. subId=%v", restSubId)
548 delete(r.restSubscriptions, restSubId)
549 c.RemoveRESTSubscriptionFromDb(restSubId)
550 }
551 }
552}