blob: aee1158c5ca0affa097211ec58d48adfcbfed657 [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
kalnagy45114752019-06-18 14:40:39 +020022import (
Juha Hyttinene406a342020-01-13 13:02:26 +020023 "fmt"
Anssi Mannilac92b4212020-12-07 14:59:34 +020024 "net/http"
25 "os"
26 "strconv"
27 "strings"
28 "time"
29
Juha Hyttinen86a46202020-01-14 12:49:09 +020030 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
kalnagy93cc3e22019-09-19 11:29:29 +020031 rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +020032 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
kalnagy1455c852019-10-21 13:06:23 +020033 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
34 httptransport "github.com/go-openapi/runtime/client"
35 "github.com/go-openapi/strfmt"
Anssi Mannilac92b4212020-12-07 14:59:34 +020036 "github.com/gorilla/mux"
archaggeafbf95f2021-04-14 08:54:05 +030037 "github.com/segmentio/ksuid"
kalnagy1455c852019-10-21 13:06:23 +020038 "github.com/spf13/viper"
kalnagy45114752019-06-18 14:40:39 +020039)
40
Juha Hyttinene406a342020-01-13 13:02:26 +020041//-----------------------------------------------------------------------------
42//
43//-----------------------------------------------------------------------------
44
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +020045func idstring(err error, entries ...fmt.Stringer) string {
46 var retval string = ""
47 var filler string = ""
48 for _, entry := range entries {
49 retval += filler + entry.String()
50 filler = " "
51 }
52 if err != nil {
53 retval += filler + "err(" + err.Error() + ")"
54 filler = " "
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +020055 }
56 return retval
57}
58
59//-----------------------------------------------------------------------------
60//
61//-----------------------------------------------------------------------------
62
Anssi Mannila2f26fb22020-12-07 08:32:13 +020063var e2tSubReqTimeout time.Duration
64var e2tSubDelReqTime time.Duration
65var e2tRecvMsgTimeout time.Duration
66var e2tMaxSubReqTryCount uint64 // Initial try + retry
67var e2tMaxSubDelReqTryCount uint64 // Initial try + retry
Anssi Mannilac92b4212020-12-07 14:59:34 +020068var readSubsFromDb string
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020069
kalnagy45114752019-06-18 14:40:39 +020070type Control struct {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +030071 *xapp.RMRClient
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +020072 e2ap *E2ap
73 registry *Registry
74 tracker *Tracker
Anssi Mannilac92b4212020-12-07 14:59:34 +020075 db Sdlnterface
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +020076 //subscriber *xapp.Subscriber
Anssi Mannilac92b4212020-12-07 14:59:34 +020077 CntRecvMsg uint64
78 ResetTestFlag bool
Anssi Mannila4abf1802021-01-28 13:06:46 +020079 Counters map[string]xapp.Counter
kalnagy93cc3e22019-09-19 11:29:29 +020080}
81
82type RMRMeid struct {
Juha Hyttinenff8dccd2019-12-10 14:34:07 +020083 PlmnID string
84 EnbID string
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020085 RanName string
kalnagy93cc3e22019-09-19 11:29:29 +020086}
87
Anssi Mannilac92b4212020-12-07 14:59:34 +020088type SubmgrRestartTestEvent struct{}
89type SubmgrRestartUpEvent struct{}
90
Peter Szilagyifbc56f92019-07-23 19:29:46 +000091func init() {
Anssi Mannila8046c702020-01-02 13:39:05 +020092 xapp.Logger.Info("SUBMGR")
Peter Szilagyifbc56f92019-07-23 19:29:46 +000093 viper.AutomaticEnv()
94 viper.SetEnvPrefix("submgr")
95 viper.AllowEmptyEnv(true)
kalnagy45114752019-06-18 14:40:39 +020096}
97
Juha Hyttinenff8dccd2019-12-10 14:34:07 +020098func NewControl() *Control {
Juha Hyttinen0388dd92020-01-09 14:14:16 +020099
Anssi Mannilac92b4212020-12-07 14:59:34 +0200100 transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
101 rtmgrClient := RtmgrClient{rtClient: rtmgrclient.New(transport, strfmt.Default)}
102
103 registry := new(Registry)
104 registry.Initialize()
105 registry.rtmgrClient = &rtmgrClient
106
107 tracker := new(Tracker)
108 tracker.Init()
109
Anssi Mannilac92b4212020-12-07 14:59:34 +0200110 c := &Control{e2ap: new(E2ap),
111 registry: registry,
112 tracker: tracker,
113 db: CreateSdl(),
114 //subscriber: subscriber,
Anssi Mannila4abf1802021-01-28 13:06:46 +0200115 Counters: xapp.Metric.RegisterCounterGroup(GetMetricsOpts(), "SUBMGR"),
Anssi Mannilac92b4212020-12-07 14:59:34 +0200116 }
Anssi Mannilaf6b78042021-02-18 12:36:59 +0200117 c.ReadConfigParameters("")
Anssi Mannilac92b4212020-12-07 14:59:34 +0200118
119 // Register REST handler for testing support
120 xapp.Resource.InjectRoute("/ric/v1/test/{testId}", c.TestRestHandler, "POST")
Abukar Mohamedfbd4df52021-03-11 06:13:27 +0000121 xapp.Resource.InjectRoute("/ric/v1/symptomdata", c.SymptomDataHandler, "GET")
Anssi Mannilac92b4212020-12-07 14:59:34 +0200122
archaggeafbf95f2021-04-14 08:54:05 +0300123 go xapp.Subscription.Listen(c.SubscriptionHandler, c.QueryHandler, c.SubscriptionDeleteHandlerCB)
Anssi Mannilac92b4212020-12-07 14:59:34 +0200124
125 if readSubsFromDb == "false" {
126 return c
127 }
128
129 // Read subscriptions from db
130 xapp.Logger.Info("Reading subscriptions from db")
131 subIds, register, err := c.ReadAllSubscriptionsFromSdl()
132 if err != nil {
133 xapp.Logger.Error("%v", err)
134 } else {
135 c.registry.subIds = subIds
136 c.registry.register = register
137 c.HandleUncompletedSubscriptions(register)
138 }
139 return c
140}
141
Abukar Mohamedfbd4df52021-03-11 06:13:27 +0000142func (c *Control) SymptomDataHandler(w http.ResponseWriter, r *http.Request) {
143 subscriptions, _ := c.registry.QueryHandler()
144 xapp.Resource.SendSymptomDataJson(w, r, subscriptions, "platform/subscriptions.json")
145}
146
Anssi Mannilac92b4212020-12-07 14:59:34 +0200147//-------------------------------------------------------------------
148//
149//-------------------------------------------------------------------
Anssi Mannilaf6b78042021-02-18 12:36:59 +0200150func (c *Control) ReadConfigParameters(f string) {
Anssi Mannilac92b4212020-12-07 14:59:34 +0200151
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200152 // viper.GetDuration returns nanoseconds
153 e2tSubReqTimeout = viper.GetDuration("controls.e2tSubReqTimeout_ms") * 1000000
Juha Hyttinen57140bc2020-12-11 13:03:06 +0200154 if e2tSubReqTimeout == 0 {
155 e2tSubReqTimeout = 2000 * 1000000
156 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200157 xapp.Logger.Info("e2tSubReqTimeout %v", e2tSubReqTimeout)
158 e2tSubDelReqTime = viper.GetDuration("controls.e2tSubDelReqTime_ms") * 1000000
Juha Hyttinen57140bc2020-12-11 13:03:06 +0200159 if e2tSubDelReqTime == 0 {
160 e2tSubDelReqTime = 2000 * 1000000
161 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200162 xapp.Logger.Info("e2tSubDelReqTime %v", e2tSubDelReqTime)
163 e2tRecvMsgTimeout = viper.GetDuration("controls.e2tRecvMsgTimeout_ms") * 1000000
Juha Hyttinen57140bc2020-12-11 13:03:06 +0200164 if e2tRecvMsgTimeout == 0 {
165 e2tRecvMsgTimeout = 2000 * 1000000
166 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200167 xapp.Logger.Info("e2tRecvMsgTimeout %v", e2tRecvMsgTimeout)
168 e2tMaxSubReqTryCount = viper.GetUint64("controls.e2tMaxSubReqTryCount")
Juha Hyttinen57140bc2020-12-11 13:03:06 +0200169 if e2tMaxSubReqTryCount == 0 {
170 e2tMaxSubReqTryCount = 1
171 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200172 xapp.Logger.Info("e2tMaxSubReqTryCount %v", e2tMaxSubReqTryCount)
173 e2tMaxSubDelReqTryCount = viper.GetUint64("controls.e2tMaxSubDelReqTryCount")
Juha Hyttinen57140bc2020-12-11 13:03:06 +0200174 if e2tMaxSubDelReqTryCount == 0 {
175 e2tMaxSubDelReqTryCount = 1
176 }
Anssi Mannila2f26fb22020-12-07 08:32:13 +0200177 xapp.Logger.Info("e2tMaxSubDelReqTryCount %v", e2tMaxSubDelReqTryCount)
178
Anssi Mannilac92b4212020-12-07 14:59:34 +0200179 readSubsFromDb = viper.GetString("controls.readSubsFromDb")
180 if readSubsFromDb == "" {
181 readSubsFromDb = "true"
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200182 }
Anssi Mannilac92b4212020-12-07 14:59:34 +0200183 xapp.Logger.Info("readSubsFromDb %v", readSubsFromDb)
184}
185
186//-------------------------------------------------------------------
187//
188//-------------------------------------------------------------------
189func (c *Control) HandleUncompletedSubscriptions(register map[uint32]*Subscription) {
190
191 xapp.Logger.Debug("HandleUncompletedSubscriptions. len(register) = %v", len(register))
192 for subId, subs := range register {
193 if subs.SubRespRcvd == false {
194 subs.NoRespToXapp = true
195 xapp.Logger.Debug("SendSubscriptionDeleteReq. subId = %v", subId)
196 c.SendSubscriptionDeleteReq(subs)
197 }
198 }
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200199}
200
201func (c *Control) ReadyCB(data interface{}) {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300202 if c.RMRClient == nil {
203 c.RMRClient = xapp.Rmr
Juha Hyttinenff8dccd2019-12-10 14:34:07 +0200204 }
kalnagy45114752019-06-18 14:40:39 +0200205}
206
207func (c *Control) Run() {
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200208 xapp.SetReadyCB(c.ReadyCB, nil)
Anssi Mannilaf6b78042021-02-18 12:36:59 +0200209 xapp.AddConfigChangeListener(c.ReadConfigParameters)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000210 xapp.Run(c)
kalnagy45114752019-06-18 14:40:39 +0200211}
212
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200213//-------------------------------------------------------------------
214//
215//-------------------------------------------------------------------
archaggea5c58bc2021-04-14 08:54:05 +0300216func (c *Control) SubscriptionHandler(params interface{}) (*models.SubscriptionResponse, error) {
archaggeafbf95f2021-04-14 08:54:05 +0300217
218 restSubId := ksuid.New().String()
219 subResp := models.SubscriptionResponse{}
220 subResp.SubscriptionID = &restSubId
221 p := params.(*models.SubscriptionParams)
222
223 c.CntRecvMsg++
224
225 c.UpdateCounter(cSubReqFromXapp)
226
227 if p.ClientEndpoint == nil {
228 xapp.Logger.Error("ClientEndpoint == nil")
229 return nil, fmt.Errorf("")
230 }
231
232 _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*p.ClientEndpoint)
233 if err != nil {
234 xapp.Logger.Error("%s", err.Error())
235 return nil, err
236 }
237
238 restSubscription, err := c.registry.CreateRESTSubscription(&restSubId, &xAppRmrEndpoint, p.Meid)
239 if err != nil {
240 xapp.Logger.Error("%s", err.Error())
241 return nil, err
242 }
243
244 subReqList := e2ap.SubscriptionRequestList{}
245 err = c.e2ap.FillSubscriptionReqMsgs(params, &subReqList, restSubscription)
246 if err != nil {
247 xapp.Logger.Error("%s", err.Error())
248 c.registry.DeleteRESTSubscription(&restSubId)
249 return nil, err
250 }
251
252 go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId)
253
254 return &subResp, nil
255
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300256}
257
archaggeafbf95f2021-04-14 08:54:05 +0300258//-------------------------------------------------------------------
259//
260//-------------------------------------------------------------------
261
262func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription, subReqList *e2ap.SubscriptionRequestList,
263 clientEndpoint *models.SubscriptionParamsClientEndpoint, meid *string, restSubId *string) {
264
265 xapp.Logger.Info("Subscription Request count=%v ", len(subReqList.E2APSubscriptionRequests))
266
267 _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*clientEndpoint)
268 if err != nil {
269 xapp.Logger.Error("%s", err.Error())
270 return
271 }
272
273 var requestorID int64
274 var instanceId int64
275 for index := 0; index < len(subReqList.E2APSubscriptionRequests); index++ {
276 subReqMsg := subReqList.E2APSubscriptionRequests[index]
277
278 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(xAppRmrEndpoint), *restSubId, subReqMsg.RequestId, &xapp.RMRMeid{RanName: *meid})
279 if trans == nil {
280 c.registry.DeleteRESTSubscription(restSubId)
281 xapp.Logger.Error("XAPP-SubReq transaction not created. RESTSubId=%s, EndPoint=%s, Meid=%s", *restSubId, xAppRmrEndpoint, *meid)
282 return
283 }
284
285 defer trans.Release()
286 xapp.Logger.Info("Handle SubscriptionRequest index=%v, %s", index, idstring(nil, trans))
287 subRespMsg, err := c.handleSubscriptionRequest(trans, &subReqMsg, meid, restSubId)
288 if err != nil {
289 // Send notification to xApp that prosessing of a Subscription Request has failed. Currently it is not possible
290 // to indicate error. Such possibility should be added. As a workaround requestorID and instanceId are set to zero value
291 requestorID = (int64)(0)
292 instanceId = (int64)(0)
293 resp := &models.SubscriptionResponse{
294 SubscriptionID: restSubId,
295 SubscriptionInstances: []*models.SubscriptionInstance{
296 &models.SubscriptionInstance{RequestorID: &requestorID, InstanceID: &instanceId},
297 },
298 }
299 // Mark REST subscription request processed.
300 restSubscription.SetProcessed()
301 xapp.Logger.Info("Sending unsuccessful REST notification to endpoint=%v:%v, InstanceId=%v, %s", clientEndpoint.Host, clientEndpoint.HTTPPort, instanceId, idstring(nil, trans))
302 xapp.Subscription.Notify(resp, *clientEndpoint)
303 } else {
304 xapp.Logger.Info("SubscriptionRequest index=%v processed successfully. endpoint=%v, InstanceId=%v, %s", index, *clientEndpoint, instanceId, idstring(nil, trans))
305
306 // Store successfully processed InstanceId for deletion
307 restSubscription.AddInstanceId(subRespMsg.RequestId.InstanceId)
308
309 // Send notification to xApp that a Subscription Request has been processed.
310 requestorID = (int64)(subRespMsg.RequestId.Id)
311 instanceId = (int64)(subRespMsg.RequestId.InstanceId)
312 resp := &models.SubscriptionResponse{
313 SubscriptionID: restSubId,
314 SubscriptionInstances: []*models.SubscriptionInstance{
315 &models.SubscriptionInstance{RequestorID: &requestorID, InstanceID: &instanceId},
316 },
317 }
318 // Mark REST subscription request processesd.
319 restSubscription.SetProcessed()
320 xapp.Logger.Info("Sending successful REST notification to endpoint=%v, InstanceId=%v, %s", *clientEndpoint, instanceId, idstring(nil, trans))
321 xapp.Subscription.Notify(resp, *clientEndpoint)
322 }
323 c.UpdateCounter(cSubRespToXapp)
324 }
325}
326
327//-------------------------------------------------------------------
328//
329//------------------------------------------------------------------
330func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, meid *string,
331 restSubId *string) (*e2ap.E2APSubscriptionResponse, error) {
332
333 err := c.tracker.Track(trans)
334 if err != nil {
335 err = fmt.Errorf("XAPP-SubReq: %s", idstring(err, trans))
336 xapp.Logger.Error("%s", err.Error())
337 return nil, err
338 }
339
340 subs, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c)
341 if err != nil {
342 err = fmt.Errorf("XAPP-SubReq: %s", idstring(err, trans))
343 xapp.Logger.Error("%s", err.Error())
344 return nil, err
345 }
346
347 //
348 // Wake subs request
349 //
350 go c.handleSubscriptionCreate(subs, trans)
351 event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
352
353 err = nil
354 if event != nil {
355 switch themsg := event.(type) {
356 case *e2ap.E2APSubscriptionResponse:
357 trans.Release()
358 return themsg, nil
359 case *e2ap.E2APSubscriptionFailure:
360 err = fmt.Errorf("SubscriptionFailure received")
361 return nil, err
362 default:
363 break
364 }
365 }
366 err = fmt.Errorf("XAPP-SubReq: failed %s", idstring(err, trans, subs))
367 xapp.Logger.Error("%s", err.Error())
368 c.registry.RemoveFromSubscription(subs, trans, 5*time.Second, c)
369 return nil, err
370}
371
372//-------------------------------------------------------------------
373//
374//-------------------------------------------------------------------
375func (c *Control) SubscriptionDeleteHandlerCB(restSubId string) error {
376
377 c.CntRecvMsg++
378 c.UpdateCounter(cSubDelReqFromXapp)
379
380 xapp.Logger.Info("SubscriptionDeleteRequest from XAPP")
381
382 restSubscription, err := c.registry.GetRESTSubscription(restSubId)
383 if err != nil {
384 xapp.Logger.Error("%s", err.Error())
385 if restSubscription == nil {
386 // Subscription was not found
387 return nil
388 } else {
389 if restSubscription.SubReqOngoing == true {
390 err := fmt.Errorf("Handling of the REST Subscription Request still ongoing %s", restSubId)
391 xapp.Logger.Error("%s", err.Error())
392 return err
393 } else if restSubscription.SubDelReqOngoing == true {
394 // Previous request for same restSubId still ongoing
395 return nil
396 }
397 }
398 }
399
400 xAppRmrEndPoint := restSubscription.xAppRmrEndPoint
401 go func() {
402 for _, instanceId := range restSubscription.InstanceIds {
403 err := c.SubscriptionDeleteHandler(&restSubId, &xAppRmrEndPoint, &restSubscription.Meid, instanceId)
404 if err != nil {
405 xapp.Logger.Error("%s", err.Error())
406 //return err
407 }
408 xapp.Logger.Info("Deleteting instanceId = %v", instanceId)
409 restSubscription.DeleteInstanceId(instanceId)
410 }
411 c.registry.DeleteRESTSubscription(&restSubId)
412 }()
413
414 c.UpdateCounter(cSubDelRespToXapp)
415
Anssi Mannilac92b4212020-12-07 14:59:34 +0200416 return nil
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200417}
418
archaggeafbf95f2021-04-14 08:54:05 +0300419//-------------------------------------------------------------------
420//
421//-------------------------------------------------------------------
422func (c *Control) SubscriptionDeleteHandler(restSubId *string, endPoint *string, meid *string, instanceId uint32) error {
423
424 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(*endPoint), *restSubId, e2ap.RequestId{0, 0}, &xapp.RMRMeid{RanName: *meid})
425 if trans == nil {
426 err := fmt.Errorf("XAPP-SubDelReq transaction not created. restSubId %s, endPoint %s, meid %s, instanceId %v", *restSubId, *endPoint, *meid, instanceId)
427 xapp.Logger.Error("%s", err.Error())
428 }
429 defer trans.Release()
430
431 err := c.tracker.Track(trans)
432 if err != nil {
433 err := fmt.Errorf("XAPP-SubDelReq %s:", idstring(err, trans))
434 xapp.Logger.Error("%s", err.Error())
435 return &time.ParseError{}
436 }
437
438 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{instanceId})
439 if err != nil {
440 err := fmt.Errorf("XAPP-SubDelReq %s:", idstring(err, trans))
441 xapp.Logger.Error("%s", err.Error())
442 return err
443 }
444 //
445 // Wake subs delete
446 //
447 go c.handleSubscriptionDelete(subs, trans)
448 trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
449
450 xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
451
452 c.registry.RemoveFromSubscription(subs, trans, 5*time.Second, c)
453
454 return nil
455}
456
457//-------------------------------------------------------------------
458//
459//-------------------------------------------------------------------
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200460func (c *Control) QueryHandler() (models.SubscriptionList, error) {
Anssi Mannila4c626a22021-02-11 12:50:48 +0200461 xapp.Logger.Info("QueryHandler() called")
462
archaggeafbf95f2021-04-14 08:54:05 +0300463 c.CntRecvMsg++
464
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200465 return c.registry.QueryHandler()
466}
467
Anssi Mannilac92b4212020-12-07 14:59:34 +0200468func (c *Control) TestRestHandler(w http.ResponseWriter, r *http.Request) {
Anssi Mannilac92b4212020-12-07 14:59:34 +0200469 xapp.Logger.Info("TestRestHandler() called")
470
471 pathParams := mux.Vars(r)
472 s := pathParams["testId"]
473
474 // This can be used to delete single subscription from db
475 if contains := strings.Contains(s, "deletesubid="); contains == true {
476 var splits = strings.Split(s, "=")
477 if subId, err := strconv.ParseInt(splits[1], 10, 64); err == nil {
478 xapp.Logger.Info("RemoveSubscriptionFromSdl() called. subId = %v", subId)
479 c.RemoveSubscriptionFromSdl(uint32(subId))
480 return
481 }
482 }
483
484 // This can be used to remove all subscriptions db from
485 if s == "emptydb" {
486 xapp.Logger.Info("RemoveAllSubscriptionsFromSdl() called")
487 c.RemoveAllSubscriptionsFromSdl()
488 return
489 }
490
491 // This is meant to cause submgr's restart in testing
492 if s == "restart" {
493 xapp.Logger.Info("os.Exit(1) called")
494 os.Exit(1)
495 }
496
497 xapp.Logger.Info("Unsupported rest command received %s", s)
498}
499
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200500//-------------------------------------------------------------------
501//
502//-------------------------------------------------------------------
503
Juha Hyttinen83ada002020-01-30 10:36:33 +0200504func (c *Control) rmrSendToE2T(desc string, subs *Subscription, trans *TransactionSubs) (err error) {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300505 params := &xapp.RMRParams{}
Juha Hyttinene406a342020-01-13 13:02:26 +0200506 params.Mtype = trans.GetMtype()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300507 params.SubId = int(subs.GetReqId().InstanceId)
Juha Hyttinen86a46202020-01-14 12:49:09 +0200508 params.Xid = ""
Juha Hyttinene406a342020-01-13 13:02:26 +0200509 params.Meid = subs.GetMeid()
510 params.Src = ""
Juha Hyttinen63284a22020-01-15 10:45:11 +0200511 params.PayloadLen = len(trans.Payload.Buf)
512 params.Payload = trans.Payload.Buf
Juha Hyttinene406a342020-01-13 13:02:26 +0200513 params.Mbuf = nil
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200514 xapp.Logger.Info("MSG to E2T: %s %s %s", desc, trans.String(), params.String())
Abukar Mohamedfbd4df52021-03-11 06:13:27 +0000515 err = c.SendWithRetry(params, false, 5)
516 if err != nil {
517 xapp.Logger.Error("rmrSendToE2T: Send failed: %+v", err)
518 }
519 return err
kalnagye0018682019-09-26 16:28:25 +0200520}
521
Juha Hyttinen83ada002020-01-30 10:36:33 +0200522func (c *Control) rmrSendToXapp(desc string, subs *Subscription, trans *TransactionXapp) (err error) {
523
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300524 params := &xapp.RMRParams{}
Juha Hyttinen63284a22020-01-15 10:45:11 +0200525 params.Mtype = trans.GetMtype()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300526 params.SubId = int(subs.GetReqId().InstanceId)
Juha Hyttinene406a342020-01-13 13:02:26 +0200527 params.Xid = trans.GetXid()
Juha Hyttinen86a46202020-01-14 12:49:09 +0200528 params.Meid = trans.GetMeid()
Juha Hyttinene406a342020-01-13 13:02:26 +0200529 params.Src = ""
Juha Hyttinen63284a22020-01-15 10:45:11 +0200530 params.PayloadLen = len(trans.Payload.Buf)
531 params.Payload = trans.Payload.Buf
Juha Hyttinene406a342020-01-13 13:02:26 +0200532 params.Mbuf = nil
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200533 xapp.Logger.Info("MSG to XAPP: %s %s %s", desc, trans.String(), params.String())
Abukar Mohamedfbd4df52021-03-11 06:13:27 +0000534 err = c.SendWithRetry(params, false, 5)
535 if err != nil {
536 xapp.Logger.Error("rmrSendToXapp: Send failed: %+v", err)
537 }
538 return err
Juha Hyttinene406a342020-01-13 13:02:26 +0200539}
540
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300541func (c *Control) Consume(msg *xapp.RMRParams) (err error) {
542 if c.RMRClient == nil {
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200543 err = fmt.Errorf("Rmr object nil can handle %s", msg.String())
544 xapp.Logger.Error("%s", err.Error())
545 return
546 }
547 c.CntRecvMsg++
548
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300549 defer c.RMRClient.Free(msg.Mbuf)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200550
Juha Hyttinena8a908d2020-05-26 15:12:47 +0300551 // xapp-frame might use direct access to c buffer and
552 // when msg.Mbuf is freed, someone might take it into use
553 // and payload data might be invalid inside message handle function
554 //
555 // subscriptions won't load system a lot so there is no
556 // real performance hit by cloning buffer into new go byte slice
557 cPay := append(msg.Payload[:0:0], msg.Payload...)
558 msg.Payload = cPay
559 msg.PayloadLen = len(cPay)
560
Anssi Mannila90fa0212019-12-12 10:47:47 +0200561 switch msg.Mtype {
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200562 case xapp.RIC_SUB_REQ:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200563 go c.handleXAPPSubscriptionRequest(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200564 case xapp.RIC_SUB_RESP:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200565 go c.handleE2TSubscriptionResponse(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200566 case xapp.RIC_SUB_FAILURE:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200567 go c.handleE2TSubscriptionFailure(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200568 case xapp.RIC_SUB_DEL_REQ:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200569 go c.handleXAPPSubscriptionDeleteRequest(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200570 case xapp.RIC_SUB_DEL_RESP:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200571 go c.handleE2TSubscriptionDeleteResponse(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200572 case xapp.RIC_SUB_DEL_FAILURE:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200573 go c.handleE2TSubscriptionDeleteFailure(msg)
Anssi Mannila90fa0212019-12-12 10:47:47 +0200574 default:
575 xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
Balint Uvegescd3881b2019-10-02 15:01:43 +0000576 }
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200577 return
Juha Hyttinen31797b42020-01-16 14:05:01 +0200578}
579
Juha Hyttinen422d0182020-01-17 13:37:05 +0200580//-------------------------------------------------------------------
581// handle from XAPP Subscription Request
582//------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300583func (c *Control) handleXAPPSubscriptionRequest(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200584 xapp.Logger.Info("MSG from XAPP: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200585 c.UpdateCounter(cSubReqFromXapp)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200586
587 subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload)
588 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200589 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200590 return
591 }
592
Anssi Mannila4c626a22021-02-11 12:50:48 +0200593 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqMsg.RequestId, params.Meid)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200594 if trans == nil {
595 xapp.Logger.Error("XAPP-SubReq: %s", idstring(fmt.Errorf("transaction not created"), params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200596 return
597 }
598 defer trans.Release()
599
Anssi Mannila6b3796f2021-02-12 09:11:35 +0200600 if err = c.tracker.Track(trans); err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200601 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
602 return
603 }
604
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300605 //TODO handle subscription toward e2term inside AssignToSubscription / hide handleSubscriptionCreate in it?
Anssi Mannila4abf1802021-01-28 13:06:46 +0200606 subs, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200607 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200608 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200609 return
610 }
611
Anssi Mannila6b3796f2021-02-12 09:11:35 +0200612 c.wakeSubscriptionRequest(subs, trans)
613}
614
615//-------------------------------------------------------------------
616// Wake Subscription Request to E2node
617//------------------------------------------------------------------
618func (c *Control) wakeSubscriptionRequest(subs *Subscription, trans *TransactionXapp) {
619
Juha Hyttinen422d0182020-01-17 13:37:05 +0200620 go c.handleSubscriptionCreate(subs, trans)
621 event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
Anssi Mannila6b3796f2021-02-12 09:11:35 +0200622 var err error
Juha Hyttinen422d0182020-01-17 13:37:05 +0200623 if event != nil {
624 switch themsg := event.(type) {
625 case *e2ap.E2APSubscriptionResponse:
Anssi Mannila4c626a22021-02-11 12:50:48 +0200626 themsg.RequestId.Id = trans.RequestId.Id
Juha Hyttinen422d0182020-01-17 13:37:05 +0200627 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(themsg)
628 if err == nil {
Anssi Mannila64a0df42020-02-26 09:46:03 +0200629 trans.Release()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200630 c.UpdateCounter(cSubRespToXapp)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200631 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200632 return
633 }
634 case *e2ap.E2APSubscriptionFailure:
Anssi Mannila4c626a22021-02-11 12:50:48 +0200635 themsg.RequestId.Id = trans.RequestId.Id
Juha Hyttinen422d0182020-01-17 13:37:05 +0200636 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(themsg)
637 if err == nil {
Anssi Mannila4abf1802021-01-28 13:06:46 +0200638 c.UpdateCounter(cSubFailToXapp)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200639 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200640 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200641 default:
Juha Hyttinen31797b42020-01-16 14:05:01 +0200642 break
643 }
644 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200645 xapp.Logger.Info("XAPP-SubReq: failed %s", idstring(err, trans, subs))
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300646 //c.registry.RemoveFromSubscription(subs, trans, 5*time.Second)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200647}
648
Juha Hyttinen422d0182020-01-17 13:37:05 +0200649//-------------------------------------------------------------------
650// handle from XAPP Subscription Delete Request
651//------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300652func (c *Control) handleXAPPSubscriptionDeleteRequest(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200653 xapp.Logger.Info("MSG from XAPP: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200654 c.UpdateCounter(cSubDelReqFromXapp)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200655
656 subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200657 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200658 xapp.Logger.Error("XAPP-SubDelReq %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200659 return
660 }
661
Anssi Mannila4c626a22021-02-11 12:50:48 +0200662 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subDelReqMsg.RequestId, params.Meid)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200663 if trans == nil {
664 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(fmt.Errorf("transaction not created"), params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200665 return
666 }
667 defer trans.Release()
668
Juha Hyttinen83ada002020-01-30 10:36:33 +0200669 err = c.tracker.Track(trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200670 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200671 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
672 return
673 }
674
Juha Hyttinen47942b42020-02-27 10:41:43 +0200675 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{trans.GetSubId()})
Juha Hyttinen83ada002020-01-30 10:36:33 +0200676 if err != nil {
677 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(err, trans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200678 return
679 }
680
Juha Hyttinen422d0182020-01-17 13:37:05 +0200681 //
682 // Wake subs delete
683 //
684 go c.handleSubscriptionDelete(subs, trans)
685 trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
686
Juha Hyttinen83ada002020-01-30 10:36:33 +0200687 xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
688
Anssi Mannilac92b4212020-12-07 14:59:34 +0200689 if subs.NoRespToXapp == true {
690 // Do no send delete responses to xapps due to submgr restart is deleting uncompleted subscriptions
691 return
692 }
693
694 // Whatever is received success, fail or timeout, send successful delete response
Juha Hyttinen422d0182020-01-17 13:37:05 +0200695 subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
Anssi Mannila4c626a22021-02-11 12:50:48 +0200696 subDelRespMsg.RequestId.Id = trans.RequestId.Id
697 subDelRespMsg.RequestId.InstanceId = subs.GetReqId().RequestId.InstanceId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200698 subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
699 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(subDelRespMsg)
700 if err == nil {
Anssi Mannila4abf1802021-01-28 13:06:46 +0200701 c.UpdateCounter(cSubDelRespToXapp)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200702 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200703 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200704
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300705 //TODO handle subscription toward e2term insiged RemoveFromSubscription / hide handleSubscriptionDelete in it?
706 //c.registry.RemoveFromSubscription(subs, trans, 5*time.Second)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200707}
708
709//-------------------------------------------------------------------
710// SUBS CREATE Handling
711//-------------------------------------------------------------------
Juha Hyttinen83ada002020-01-30 10:36:33 +0200712func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *TransactionXapp) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200713
Anssi Mannilac92b4212020-12-07 14:59:34 +0200714 var removeSubscriptionFromDb bool = false
Juha Hyttinen83ada002020-01-30 10:36:33 +0200715 trans := c.tracker.NewSubsTransaction(subs)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200716 subs.WaitTransactionTurn(trans)
717 defer subs.ReleaseTransactionTurn(trans)
718 defer trans.Release()
719
Juha Hyttinen83ada002020-01-30 10:36:33 +0200720 xapp.Logger.Debug("SUBS-SubReq: Handling %s ", idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200721
Juha Hyttinen83ada002020-01-30 10:36:33 +0200722 subRfMsg, valid := subs.GetCachedResponse()
723 if subRfMsg == nil && valid == true {
Anssi Mannila6d629ad2021-01-25 09:59:56 +0200724 event := c.sendE2TSubscriptionRequest(subs, trans, parentTrans)
725 switch event.(type) {
726 case *e2ap.E2APSubscriptionResponse:
727 subRfMsg, valid = subs.SetCachedResponse(event, true)
728 subs.SubRespRcvd = true
729 case *e2ap.E2APSubscriptionFailure:
730 removeSubscriptionFromDb = true
731 subRfMsg, valid = subs.SetCachedResponse(event, false)
Anssi Mannilaebaeae62021-02-12 11:56:20 +0200732 xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
archaggeafbf95f2021-04-14 08:54:05 +0300733 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
Anssi Mannila6d629ad2021-01-25 09:59:56 +0200734 case *SubmgrRestartTestEvent:
735 // This simulates that no response has been received and after restart subscriptions are restored from db
736 xapp.Logger.Debug("Test restart flag is active. Dropping this transaction to test restart case")
737 return
738 default:
739 xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
740 removeSubscriptionFromDb = true
741 subRfMsg, valid = subs.SetCachedResponse(nil, false)
742 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200743 }
744 xapp.Logger.Debug("SUBS-SubReq: Handling (e2t response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
745 } else {
746 xapp.Logger.Debug("SUBS-SubReq: Handling (cached response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200747 }
748
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300749 //Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
750 if valid == false {
Anssi Mannilac92b4212020-12-07 14:59:34 +0200751 c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second, c)
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300752 }
Anssi Mannilac92b4212020-12-07 14:59:34 +0200753
754 c.UpdateSubscriptionInDB(subs, removeSubscriptionFromDb)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200755 parentTrans.SendEvent(subRfMsg, 0)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200756}
757
758//-------------------------------------------------------------------
759// SUBS DELETE Handling
760//-------------------------------------------------------------------
Juha Hyttinen3944a222020-01-24 11:51:46 +0200761
Juha Hyttinen83ada002020-01-30 10:36:33 +0200762func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *TransactionXapp) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200763
Juha Hyttinen83ada002020-01-30 10:36:33 +0200764 trans := c.tracker.NewSubsTransaction(subs)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200765 subs.WaitTransactionTurn(trans)
766 defer subs.ReleaseTransactionTurn(trans)
767 defer trans.Release()
768
Juha Hyttinen83ada002020-01-30 10:36:33 +0200769 xapp.Logger.Debug("SUBS-SubDelReq: Handling %s", idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200770
Juha Hyttinen3944a222020-01-24 11:51:46 +0200771 subs.mutex.Lock()
Anssi Mannila4abf1802021-01-28 13:06:46 +0200772
Juha Hyttinen3944a222020-01-24 11:51:46 +0200773 if subs.valid && subs.EpList.HasEndpoint(parentTrans.GetEndpoint()) && subs.EpList.Size() == 1 {
774 subs.valid = false
775 subs.mutex.Unlock()
776 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
777 } else {
778 subs.mutex.Unlock()
779 }
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300780 //Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
781 // If parallel deletes ongoing both might pass earlier sendE2TSubscriptionDeleteRequest(...) if
782 // RemoveFromSubscription locates in caller side (now in handleXAPPSubscriptionDeleteRequest(...))
Anssi Mannilac92b4212020-12-07 14:59:34 +0200783 c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second, c)
784 c.registry.UpdateSubscriptionToDb(subs, c)
Juha Hyttinen47942b42020-02-27 10:41:43 +0200785 parentTrans.SendEvent(nil, 0)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200786}
787
788//-------------------------------------------------------------------
789// send to E2T Subscription Request
790//-------------------------------------------------------------------
Juha Hyttinen83ada002020-01-30 10:36:33 +0200791func (c *Control) sendE2TSubscriptionRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp) interface{} {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200792 var err error
793 var event interface{} = nil
794 var timedOut bool = false
795
796 subReqMsg := subs.SubReqMsg
Juha Hyttinen83ada002020-01-30 10:36:33 +0200797 subReqMsg.RequestId = subs.GetReqId().RequestId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200798 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(subReqMsg)
799 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200800 xapp.Logger.Error("SUBS-SubReq: %s", idstring(err, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200801 return event
802 }
803
Anssi Mannilac92b4212020-12-07 14:59:34 +0200804 // Write uncompleted subscrition in db. If no response for subscrition it need to be re-processed (deleted) after restart
805 c.WriteSubscriptionToDb(subs)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200806 for retries := uint64(0); retries < e2tMaxSubReqTryCount; retries++ {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200807 desc := fmt.Sprintf("(retry %d)", retries)
Anssi Mannila4abf1802021-01-28 13:06:46 +0200808 if retries == 0 {
809 c.UpdateCounter(cSubReqToE2)
810 } else {
811 c.UpdateCounter(cSubReReqToE2)
812 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200813 c.rmrSendToE2T(desc, subs, trans)
Anssi Mannilac92b4212020-12-07 14:59:34 +0200814 if subs.DoNotWaitSubResp == false {
815 event, timedOut = trans.WaitEvent(e2tSubReqTimeout)
816 if timedOut {
Anssi Mannila4abf1802021-01-28 13:06:46 +0200817 c.UpdateCounter(cSubReqTimerExpiry)
Anssi Mannilac92b4212020-12-07 14:59:34 +0200818 continue
819 }
820 } else {
821 // Simulating case where subscrition request has been sent but response has not been received before restart
822 event = &SubmgrRestartTestEvent{}
Juha Hyttinen422d0182020-01-17 13:37:05 +0200823 }
824 break
825 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200826 xapp.Logger.Debug("SUBS-SubReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200827 return event
828}
829
830//-------------------------------------------------------------------
831// send to E2T Subscription Delete Request
832//-------------------------------------------------------------------
833
Juha Hyttinen83ada002020-01-30 10:36:33 +0200834func (c *Control) sendE2TSubscriptionDeleteRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp) interface{} {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200835 var err error
836 var event interface{}
837 var timedOut bool
838
839 subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
Juha Hyttinen83ada002020-01-30 10:36:33 +0200840 subDelReqMsg.RequestId = subs.GetReqId().RequestId
Juha Hyttinenaf91f972020-01-24 08:38:47 +0200841 subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200842 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
843 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200844 xapp.Logger.Error("SUBS-SubDelReq: %s", idstring(err, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200845 return event
846 }
847
848 for retries := uint64(0); retries < e2tMaxSubDelReqTryCount; retries++ {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200849 desc := fmt.Sprintf("(retry %d)", retries)
Anssi Mannila4abf1802021-01-28 13:06:46 +0200850 if retries == 0 {
851 c.UpdateCounter(cSubDelReqToE2)
852 } else {
853 c.UpdateCounter(cSubDelReReqToE2)
854 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200855 c.rmrSendToE2T(desc, subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200856 event, timedOut = trans.WaitEvent(e2tSubDelReqTime)
857 if timedOut {
Anssi Mannila4abf1802021-01-28 13:06:46 +0200858 c.UpdateCounter(cSubDelReqTimerExpiry)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200859 continue
860 }
861 break
862 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200863 xapp.Logger.Debug("SUBS-SubDelReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200864 return event
865}
866
867//-------------------------------------------------------------------
Anssi Mannila4abf1802021-01-28 13:06:46 +0200868// handle from E2T Subscription Response
Juha Hyttinen422d0182020-01-17 13:37:05 +0200869//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300870func (c *Control) handleE2TSubscriptionResponse(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200871 xapp.Logger.Info("MSG from E2T: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200872 c.UpdateCounter(cSubRespFromE2)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200873 subRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
874 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200875 xapp.Logger.Error("MSG-SubResp %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200876 return
877 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300878 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subRespMsg.RequestId.InstanceId})
Juha Hyttinen422d0182020-01-17 13:37:05 +0200879 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200880 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200881 return
Juha Hyttinen31797b42020-01-16 14:05:01 +0200882 }
883 trans := subs.GetTransaction()
884 if trans == nil {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200885 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200886 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params, subs))
Juha Hyttinenff8dccd2019-12-10 14:34:07 +0200887 return
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200888 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200889 sendOk, timedOut := trans.SendEvent(subRespMsg, e2tRecvMsgTimeout)
890 if sendOk == false {
891 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200892 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, trans, subs))
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000893 }
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000894 return
kalnagy45114752019-06-18 14:40:39 +0200895}
896
Juha Hyttinen422d0182020-01-17 13:37:05 +0200897//-------------------------------------------------------------------
898// handle from E2T Subscription Failure
899//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300900func (c *Control) handleE2TSubscriptionFailure(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200901 xapp.Logger.Info("MSG from E2T: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200902 c.UpdateCounter(cSubFailFromE2)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200903 subFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000904 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200905 xapp.Logger.Error("MSG-SubFail %s", idstring(err, params))
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000906 return
907 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300908 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subFailMsg.RequestId.InstanceId})
Juha Hyttinen31797b42020-01-16 14:05:01 +0200909 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200910 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params))
Juha Hyttinenaafee7f2020-01-14 14:54:51 +0200911 return
912 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200913 trans := subs.GetTransaction()
914 if trans == nil {
915 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200916 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200917 return
918 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200919 sendOk, timedOut := trans.SendEvent(subFailMsg, e2tRecvMsgTimeout)
920 if sendOk == false {
921 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200922 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, trans, subs))
Juha Hyttinenaafee7f2020-01-14 14:54:51 +0200923 }
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200924 return
925}
926
Juha Hyttinen422d0182020-01-17 13:37:05 +0200927//-------------------------------------------------------------------
928// handle from E2T Subscription Delete Response
929//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300930func (c *Control) handleE2TSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200931 xapp.Logger.Info("MSG from E2T: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200932 c.UpdateCounter(cSubDelRespFromE2)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200933 subDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload)
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200934 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200935 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200936 return
937 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300938 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelRespMsg.RequestId.InstanceId})
Juha Hyttinen31797b42020-01-16 14:05:01 +0200939 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200940 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
Juha Hyttinen0d064ec2020-01-09 09:08:53 +0200941 return
942 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200943 trans := subs.GetTransaction()
944 if trans == nil {
945 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200946 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200947 return
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200948 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200949 sendOk, timedOut := trans.SendEvent(subDelRespMsg, e2tRecvMsgTimeout)
950 if sendOk == false {
951 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200952 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, trans, subs))
Juha Hyttinen60bfcf92020-01-14 15:14:24 +0200953 }
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200954 return
955}
956
Juha Hyttinen422d0182020-01-17 13:37:05 +0200957//-------------------------------------------------------------------
958// handle from E2T Subscription Delete Failure
959//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300960func (c *Control) handleE2TSubscriptionDeleteFailure(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200961 xapp.Logger.Info("MSG from E2T: %s", params.String())
Anssi Mannila4abf1802021-01-28 13:06:46 +0200962 c.UpdateCounter(cSubDelFailFromE2)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200963 subDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200964 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200965 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
Anssi Mannilaf1d0eb62019-12-17 15:29:55 +0200966 return
967 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300968 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelFailMsg.RequestId.InstanceId})
Anssi Mannila8046c702020-01-02 13:39:05 +0200969 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200970 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
Anssi Mannila8046c702020-01-02 13:39:05 +0200971 return
972 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200973 trans := subs.GetTransaction()
974 if trans == nil {
975 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200976 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params, subs))
Juha Hyttinen86a46202020-01-14 12:49:09 +0200977 return
978 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200979 sendOk, timedOut := trans.SendEvent(subDelFailMsg, e2tRecvMsgTimeout)
980 if sendOk == false {
981 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200982 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, trans, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200983 }
kalnagy93cc3e22019-09-19 11:29:29 +0200984 return
985}
986
Juha Hyttinen422d0182020-01-17 13:37:05 +0200987//-------------------------------------------------------------------
988//
989//-------------------------------------------------------------------
990func typeofSubsMessage(v interface{}) string {
991 if v == nil {
992 return "NIL"
kalnagy93cc3e22019-09-19 11:29:29 +0200993 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200994 switch v.(type) {
995 case *e2ap.E2APSubscriptionRequest:
996 return "SubReq"
997 case *e2ap.E2APSubscriptionResponse:
998 return "SubResp"
999 case *e2ap.E2APSubscriptionFailure:
1000 return "SubFail"
1001 case *e2ap.E2APSubscriptionDeleteRequest:
1002 return "SubDelReq"
1003 case *e2ap.E2APSubscriptionDeleteResponse:
1004 return "SubDelResp"
1005 case *e2ap.E2APSubscriptionDeleteFailure:
1006 return "SubDelFail"
1007 default:
1008 return "Unknown"
Juha Hyttinen31797b42020-01-16 14:05:01 +02001009 }
Anssi Mannilaf1d0eb62019-12-17 15:29:55 +02001010}
Anssi Mannilac92b4212020-12-07 14:59:34 +02001011
1012//-------------------------------------------------------------------
1013//
1014//-------------------------------------------------------------------
1015func (c *Control) WriteSubscriptionToDb(subs *Subscription) {
1016 xapp.Logger.Debug("WriteSubscriptionToDb() subId = %v", subs.ReqId.InstanceId)
1017 err := c.WriteSubscriptionToSdl(subs.ReqId.InstanceId, subs)
1018 if err != nil {
1019 xapp.Logger.Error("%v", err)
1020 }
1021}
1022
1023//-------------------------------------------------------------------
1024//
1025//-------------------------------------------------------------------
1026func (c *Control) UpdateSubscriptionInDB(subs *Subscription, removeSubscriptionFromDb bool) {
1027
1028 if removeSubscriptionFromDb == true {
1029 // Subscription was written in db already when subscription request was sent to BTS, except for merged request
1030 c.RemoveSubscriptionFromDb(subs)
1031 } else {
1032 // Update is needed for successful response and merge case here
1033 if subs.RetryFromXapp == false {
1034 c.WriteSubscriptionToDb(subs)
1035 }
1036 }
1037 subs.RetryFromXapp = false
1038}
1039
1040//-------------------------------------------------------------------
1041//
1042//-------------------------------------------------------------------
1043func (c *Control) RemoveSubscriptionFromDb(subs *Subscription) {
1044 xapp.Logger.Debug("RemoveSubscriptionFromDb() subId = %v", subs.ReqId.InstanceId)
1045 err := c.RemoveSubscriptionFromSdl(subs.ReqId.InstanceId)
1046 if err != nil {
1047 xapp.Logger.Error("%v", err)
1048 }
1049}
1050
1051func (c *Control) SendSubscriptionDeleteReq(subs *Subscription) {
1052
1053 xapp.Logger.Debug("Sending subscription delete due to restart. subId = %v", subs.ReqId.InstanceId)
1054
1055 // Send delete for every endpoint in the subscription
1056 subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
1057 subDelReqMsg.RequestId = subs.GetReqId().RequestId
1058 subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
1059 mType, payload, err := c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
1060 if err != nil {
1061 xapp.Logger.Error("SendSubscriptionDeleteReq() %s", idstring(err))
1062 return
1063 }
1064 for _, endPoint := range subs.EpList.Endpoints {
1065 params := &xapp.RMRParams{}
1066 params.Mtype = mType
1067 params.SubId = int(subs.GetReqId().InstanceId)
1068 params.Xid = ""
1069 params.Meid = subs.Meid
1070 params.Src = endPoint.String()
1071 params.PayloadLen = len(payload.Buf)
1072 params.Payload = payload.Buf
1073 params.Mbuf = nil
Anssi Mannilac92b4212020-12-07 14:59:34 +02001074 subs.DeleteFromDb = true
1075 c.handleXAPPSubscriptionDeleteRequest(params)
1076 }
1077}