blob: a5d81fb1bf7ce8fb14b1e2c9b743efe39ba94c5f [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"
Juha Hyttinen86a46202020-01-14 12:49:09 +020024 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
kalnagy93cc3e22019-09-19 11:29:29 +020025 rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +020026 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
kalnagy1455c852019-10-21 13:06:23 +020027 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
28 httptransport "github.com/go-openapi/runtime/client"
29 "github.com/go-openapi/strfmt"
30 "github.com/spf13/viper"
Peter Szilagyifbc56f92019-07-23 19:29:46 +000031 "time"
kalnagy45114752019-06-18 14:40:39 +020032)
33
Juha Hyttinene406a342020-01-13 13:02:26 +020034//-----------------------------------------------------------------------------
35//
36//-----------------------------------------------------------------------------
37
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +020038func idstring(err error, entries ...fmt.Stringer) string {
39 var retval string = ""
40 var filler string = ""
41 for _, entry := range entries {
42 retval += filler + entry.String()
43 filler = " "
44 }
45 if err != nil {
46 retval += filler + "err(" + err.Error() + ")"
47 filler = " "
48
49 }
50 return retval
51}
52
53//-----------------------------------------------------------------------------
54//
55//-----------------------------------------------------------------------------
56
Anssi Mannila2f26fb22020-12-07 08:32:13 +020057var e2tSubReqTimeout time.Duration
58var e2tSubDelReqTime time.Duration
59var e2tRecvMsgTimeout time.Duration
60var e2tMaxSubReqTryCount uint64 // Initial try + retry
61var e2tMaxSubDelReqTryCount uint64 // Initial try + retry
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020062
kalnagy45114752019-06-18 14:40:39 +020063type Control struct {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +030064 *xapp.RMRClient
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +020065 e2ap *E2ap
66 registry *Registry
67 tracker *Tracker
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +020068 //subscriber *xapp.Subscriber
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +030069 CntRecvMsg uint64
kalnagy93cc3e22019-09-19 11:29:29 +020070}
71
72type RMRMeid struct {
Juha Hyttinenff8dccd2019-12-10 14:34:07 +020073 PlmnID string
74 EnbID string
Anssi Mannila2e99e2f2019-12-05 13:57:06 +020075 RanName string
kalnagy93cc3e22019-09-19 11:29:29 +020076}
77
Peter Szilagyifbc56f92019-07-23 19:29:46 +000078func init() {
Anssi Mannila8046c702020-01-02 13:39:05 +020079 xapp.Logger.Info("SUBMGR")
Peter Szilagyifbc56f92019-07-23 19:29:46 +000080 viper.AutomaticEnv()
81 viper.SetEnvPrefix("submgr")
82 viper.AllowEmptyEnv(true)
kalnagy45114752019-06-18 14:40:39 +020083}
84
Juha Hyttinenff8dccd2019-12-10 14:34:07 +020085func NewControl() *Control {
Juha Hyttinen0388dd92020-01-09 14:14:16 +020086
Anssi Mannila2f26fb22020-12-07 08:32:13 +020087 // viper.GetDuration returns nanoseconds
88 e2tSubReqTimeout = viper.GetDuration("controls.e2tSubReqTimeout_ms") * 1000000
89 xapp.Logger.Info("e2tSubReqTimeout %v", e2tSubReqTimeout)
90 e2tSubDelReqTime = viper.GetDuration("controls.e2tSubDelReqTime_ms") * 1000000
91 xapp.Logger.Info("e2tSubDelReqTime %v", e2tSubDelReqTime)
92 e2tRecvMsgTimeout = viper.GetDuration("controls.e2tRecvMsgTimeout_ms") * 1000000
93 xapp.Logger.Info("e2tRecvMsgTimeout %v", e2tRecvMsgTimeout)
94 e2tMaxSubReqTryCount = viper.GetUint64("controls.e2tMaxSubReqTryCount")
95 xapp.Logger.Info("e2tMaxSubReqTryCount %v", e2tMaxSubReqTryCount)
96 e2tMaxSubDelReqTryCount = viper.GetUint64("controls.e2tMaxSubDelReqTryCount")
97 xapp.Logger.Info("e2tMaxSubDelReqTryCount %v", e2tMaxSubDelReqTryCount)
98
Juha Hyttinen56e03832020-01-14 17:08:43 +020099 transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
Juha Hyttinen12d31af2020-01-22 12:59:01 +0200100 rtmgrClient := RtmgrClient{rtClient: rtmgrclient.New(transport, strfmt.Default)}
Juha Hyttinen56e03832020-01-14 17:08:43 +0200101
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000102 registry := new(Registry)
Anssi Mannila5c161a92020-01-15 15:40:57 +0200103 registry.Initialize()
Juha Hyttinen56e03832020-01-14 17:08:43 +0200104 registry.rtmgrClient = &rtmgrClient
kalnagy93cc3e22019-09-19 11:29:29 +0200105
Balint Uvegese9608cd2019-09-20 18:00:32 +0000106 tracker := new(Tracker)
107 tracker.Init()
108
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200109 //subscriber := xapp.NewSubscriber(viper.GetString("subscription.host"), viper.GetInt("subscription.timeout"))
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200110
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200111 c := &Control{e2ap: new(E2ap),
112 registry: registry,
113 tracker: tracker,
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200114 //subscriber: subscriber,
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200115 }
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300116 go xapp.Subscription.Listen(c.SubscriptionHandler, c.QueryHandler, c.SubscriptionDeleteHandler)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200117 //go c.subscriber.Listen(c.SubscriptionHandler, c.QueryHandler)
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200118 return c
119}
120
121func (c *Control) ReadyCB(data interface{}) {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300122 if c.RMRClient == nil {
123 c.RMRClient = xapp.Rmr
Juha Hyttinenff8dccd2019-12-10 14:34:07 +0200124 }
kalnagy45114752019-06-18 14:40:39 +0200125}
126
127func (c *Control) Run() {
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200128 xapp.SetReadyCB(c.ReadyCB, nil)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000129 xapp.Run(c)
kalnagy45114752019-06-18 14:40:39 +0200130}
131
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200132//-------------------------------------------------------------------
133//
134//-------------------------------------------------------------------
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300135func (c *Control) SubscriptionHandler(stype models.SubscriptionType, params interface{}) (*models.SubscriptionResponse, error) {
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200136 /*
137 switch p := params.(type) {
138 case *models.ReportParams:
139 trans := c.tracker.NewXappTransaction(NewRmrEndpoint(p.ClientEndpoint),"" , 0, &xapp.RMRMeid{RanName: p.Meid})
140 if trans == nil {
141 xapp.Logger.Error("XAPP-SubReq: %s", idstring(fmt.Errorf("transaction not created"), params))
142 return
143 }
144 defer trans.Release()
145 case *models.ControlParams:
146 case *models.PolicyParams:
147 }
148 */
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300149 return &models.SubscriptionResponse{}, fmt.Errorf("Subscription rest interface not implemented")
150}
151
152func (c *Control) SubscriptionDeleteHandler(string) error {
153 return fmt.Errorf("Subscription rest interface not implemented")
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200154}
155
156func (c *Control) QueryHandler() (models.SubscriptionList, error) {
157 return c.registry.QueryHandler()
158}
159
160//-------------------------------------------------------------------
161//
162//-------------------------------------------------------------------
163
Juha Hyttinen83ada002020-01-30 10:36:33 +0200164func (c *Control) rmrSendToE2T(desc string, subs *Subscription, trans *TransactionSubs) (err error) {
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300165 params := &xapp.RMRParams{}
Juha Hyttinene406a342020-01-13 13:02:26 +0200166 params.Mtype = trans.GetMtype()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300167 params.SubId = int(subs.GetReqId().InstanceId)
Juha Hyttinen86a46202020-01-14 12:49:09 +0200168 params.Xid = ""
Juha Hyttinene406a342020-01-13 13:02:26 +0200169 params.Meid = subs.GetMeid()
170 params.Src = ""
Juha Hyttinen63284a22020-01-15 10:45:11 +0200171 params.PayloadLen = len(trans.Payload.Buf)
172 params.Payload = trans.Payload.Buf
Juha Hyttinene406a342020-01-13 13:02:26 +0200173 params.Mbuf = nil
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200174 xapp.Logger.Info("MSG to E2T: %s %s %s", desc, trans.String(), params.String())
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300175 return c.SendWithRetry(params, false, 5)
kalnagye0018682019-09-26 16:28:25 +0200176}
177
Juha Hyttinen83ada002020-01-30 10:36:33 +0200178func (c *Control) rmrSendToXapp(desc string, subs *Subscription, trans *TransactionXapp) (err error) {
179
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300180 params := &xapp.RMRParams{}
Juha Hyttinen63284a22020-01-15 10:45:11 +0200181 params.Mtype = trans.GetMtype()
Juha Hyttinenaada6452020-04-07 08:47:58 +0300182 params.SubId = int(subs.GetReqId().InstanceId)
Juha Hyttinene406a342020-01-13 13:02:26 +0200183 params.Xid = trans.GetXid()
Juha Hyttinen86a46202020-01-14 12:49:09 +0200184 params.Meid = trans.GetMeid()
Juha Hyttinene406a342020-01-13 13:02:26 +0200185 params.Src = ""
Juha Hyttinen63284a22020-01-15 10:45:11 +0200186 params.PayloadLen = len(trans.Payload.Buf)
187 params.Payload = trans.Payload.Buf
Juha Hyttinene406a342020-01-13 13:02:26 +0200188 params.Mbuf = nil
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200189 xapp.Logger.Info("MSG to XAPP: %s %s %s", desc, trans.String(), params.String())
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300190 return c.SendWithRetry(params, false, 5)
Juha Hyttinene406a342020-01-13 13:02:26 +0200191}
192
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300193func (c *Control) Consume(msg *xapp.RMRParams) (err error) {
194 if c.RMRClient == nil {
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200195 err = fmt.Errorf("Rmr object nil can handle %s", msg.String())
196 xapp.Logger.Error("%s", err.Error())
197 return
198 }
199 c.CntRecvMsg++
200
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300201 defer c.RMRClient.Free(msg.Mbuf)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200202
Juha Hyttinena8a908d2020-05-26 15:12:47 +0300203 // xapp-frame might use direct access to c buffer and
204 // when msg.Mbuf is freed, someone might take it into use
205 // and payload data might be invalid inside message handle function
206 //
207 // subscriptions won't load system a lot so there is no
208 // real performance hit by cloning buffer into new go byte slice
209 cPay := append(msg.Payload[:0:0], msg.Payload...)
210 msg.Payload = cPay
211 msg.PayloadLen = len(cPay)
212
Anssi Mannila90fa0212019-12-12 10:47:47 +0200213 switch msg.Mtype {
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200214 case xapp.RIC_SUB_REQ:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200215 go c.handleXAPPSubscriptionRequest(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200216 case xapp.RIC_SUB_RESP:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200217 go c.handleE2TSubscriptionResponse(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200218 case xapp.RIC_SUB_FAILURE:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200219 go c.handleE2TSubscriptionFailure(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200220 case xapp.RIC_SUB_DEL_REQ:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200221 go c.handleXAPPSubscriptionDeleteRequest(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200222 case xapp.RIC_SUB_DEL_RESP:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200223 go c.handleE2TSubscriptionDeleteResponse(msg)
Juha Hyttinenc9eb08a2020-02-28 08:53:33 +0200224 case xapp.RIC_SUB_DEL_FAILURE:
Juha Hyttinen422d0182020-01-17 13:37:05 +0200225 go c.handleE2TSubscriptionDeleteFailure(msg)
Anssi Mannila90fa0212019-12-12 10:47:47 +0200226 default:
227 xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
Balint Uvegescd3881b2019-10-02 15:01:43 +0000228 }
Juha Hyttinen5f8ffa02020-02-06 15:28:59 +0200229 return
Juha Hyttinen31797b42020-01-16 14:05:01 +0200230}
231
Juha Hyttinen422d0182020-01-17 13:37:05 +0200232//-------------------------------------------------------------------
233// handle from XAPP Subscription Request
234//------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300235func (c *Control) handleXAPPSubscriptionRequest(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200236 xapp.Logger.Info("MSG from XAPP: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200237
238 subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload)
239 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200240 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200241 return
242 }
243
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300244 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqMsg.RequestId.InstanceId, params.Meid)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200245 if trans == nil {
246 xapp.Logger.Error("XAPP-SubReq: %s", idstring(fmt.Errorf("transaction not created"), params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200247 return
248 }
249 defer trans.Release()
250
Juha Hyttinen83ada002020-01-30 10:36:33 +0200251 err = c.tracker.Track(trans)
252 if err != nil {
253 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
254 return
255 }
256
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300257 //TODO handle subscription toward e2term inside AssignToSubscription / hide handleSubscriptionCreate in it?
Juha Hyttinen422d0182020-01-17 13:37:05 +0200258 subs, err := c.registry.AssignToSubscription(trans, subReqMsg)
259 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200260 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200261 return
262 }
263
Juha Hyttinen422d0182020-01-17 13:37:05 +0200264 //
265 // Wake subs request
266 //
267 go c.handleSubscriptionCreate(subs, trans)
268 event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
269
270 err = nil
271 if event != nil {
272 switch themsg := event.(type) {
273 case *e2ap.E2APSubscriptionResponse:
274 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(themsg)
275 if err == nil {
Anssi Mannila64a0df42020-02-26 09:46:03 +0200276 trans.Release()
Juha Hyttinen83ada002020-01-30 10:36:33 +0200277 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200278 return
279 }
280 case *e2ap.E2APSubscriptionFailure:
281 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(themsg)
282 if err == nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200283 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200284 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200285 default:
Juha Hyttinen31797b42020-01-16 14:05:01 +0200286 break
287 }
288 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200289 xapp.Logger.Info("XAPP-SubReq: failed %s", idstring(err, trans, subs))
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300290 //c.registry.RemoveFromSubscription(subs, trans, 5*time.Second)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200291}
292
Juha Hyttinen422d0182020-01-17 13:37:05 +0200293//-------------------------------------------------------------------
294// handle from XAPP Subscription Delete Request
295//------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300296func (c *Control) handleXAPPSubscriptionDeleteRequest(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200297 xapp.Logger.Info("MSG from XAPP: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200298
299 subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200300 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200301 xapp.Logger.Error("XAPP-SubDelReq %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200302 return
303 }
304
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300305 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subDelReqMsg.RequestId.InstanceId, params.Meid)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200306 if trans == nil {
307 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(fmt.Errorf("transaction not created"), params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200308 return
309 }
310 defer trans.Release()
311
Juha Hyttinen83ada002020-01-30 10:36:33 +0200312 err = c.tracker.Track(trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200313 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200314 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
315 return
316 }
317
Juha Hyttinen47942b42020-02-27 10:41:43 +0200318 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{trans.GetSubId()})
Juha Hyttinen83ada002020-01-30 10:36:33 +0200319 if err != nil {
320 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(err, trans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200321 return
322 }
323
Juha Hyttinen422d0182020-01-17 13:37:05 +0200324 //
325 // Wake subs delete
326 //
327 go c.handleSubscriptionDelete(subs, trans)
328 trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
329
Juha Hyttinen83ada002020-01-30 10:36:33 +0200330 xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
331
Juha Hyttinen422d0182020-01-17 13:37:05 +0200332 // Whatever is received send ok delete response
333 subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
Juha Hyttinen47942b42020-02-27 10:41:43 +0200334 subDelRespMsg.RequestId = subs.GetReqId().RequestId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200335 subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
336 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(subDelRespMsg)
337 if err == nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200338 c.rmrSendToXapp("", subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200339 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200340
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300341 //TODO handle subscription toward e2term insiged RemoveFromSubscription / hide handleSubscriptionDelete in it?
342 //c.registry.RemoveFromSubscription(subs, trans, 5*time.Second)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200343}
344
345//-------------------------------------------------------------------
346// SUBS CREATE Handling
347//-------------------------------------------------------------------
Juha Hyttinen83ada002020-01-30 10:36:33 +0200348func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *TransactionXapp) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200349
Juha Hyttinen83ada002020-01-30 10:36:33 +0200350 trans := c.tracker.NewSubsTransaction(subs)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200351 subs.WaitTransactionTurn(trans)
352 defer subs.ReleaseTransactionTurn(trans)
353 defer trans.Release()
354
Juha Hyttinen83ada002020-01-30 10:36:33 +0200355 xapp.Logger.Debug("SUBS-SubReq: Handling %s ", idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200356
Juha Hyttinen83ada002020-01-30 10:36:33 +0200357 subRfMsg, valid := subs.GetCachedResponse()
358 if subRfMsg == nil && valid == true {
Juha Hyttinenf28853b2020-03-09 14:02:50 +0200359
360 //
361 // In case of failure
362 // - make internal delete
363 // - in case duplicate cause, retry (currently max 1 retry)
364 //
365 maxRetries := uint64(1)
366 doRetry := true
367 for retries := uint64(0); retries <= maxRetries && doRetry; retries++ {
368 doRetry = false
369
370 event := c.sendE2TSubscriptionRequest(subs, trans, parentTrans)
371 switch themsg := event.(type) {
372 case *e2ap.E2APSubscriptionResponse:
373 subRfMsg, valid = subs.SetCachedResponse(event, true)
374 case *e2ap.E2APSubscriptionFailure:
375 subRfMsg, valid = subs.SetCachedResponse(event, false)
376 doRetry = true
377 for _, item := range themsg.ActionNotAdmittedList.Items {
378 if item.Cause.Content != e2ap.E2AP_CauseContent_Ric || (item.Cause.Value != e2ap.E2AP_CauseValue_Ric_duplicate_action && item.Cause.Value != e2ap.E2AP_CauseValue_Ric_duplicate_event) {
379 doRetry = false
380 break
381 }
382 }
383 xapp.Logger.Info("SUBS-SubReq: internal delete and possible retry due event(%s) retry(%t,%d/%d) %s", typeofSubsMessage(event), doRetry, retries, maxRetries, idstring(nil, trans, subs, parentTrans))
384 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
385 default:
386 xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
387 subRfMsg, valid = subs.SetCachedResponse(nil, false)
388 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
389 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200390 }
Juha Hyttinenf28853b2020-03-09 14:02:50 +0200391
Juha Hyttinen83ada002020-01-30 10:36:33 +0200392 xapp.Logger.Debug("SUBS-SubReq: Handling (e2t response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
393 } else {
394 xapp.Logger.Debug("SUBS-SubReq: Handling (cached response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200395 }
396
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300397 //Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
398 if valid == false {
399 c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
400 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200401 parentTrans.SendEvent(subRfMsg, 0)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200402}
403
404//-------------------------------------------------------------------
405// SUBS DELETE Handling
406//-------------------------------------------------------------------
Juha Hyttinen3944a222020-01-24 11:51:46 +0200407
Juha Hyttinen83ada002020-01-30 10:36:33 +0200408func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *TransactionXapp) {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200409
Juha Hyttinen83ada002020-01-30 10:36:33 +0200410 trans := c.tracker.NewSubsTransaction(subs)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200411 subs.WaitTransactionTurn(trans)
412 defer subs.ReleaseTransactionTurn(trans)
413 defer trans.Release()
414
Juha Hyttinen83ada002020-01-30 10:36:33 +0200415 xapp.Logger.Debug("SUBS-SubDelReq: Handling %s", idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200416
Juha Hyttinen3944a222020-01-24 11:51:46 +0200417 subs.mutex.Lock()
418 if subs.valid && subs.EpList.HasEndpoint(parentTrans.GetEndpoint()) && subs.EpList.Size() == 1 {
419 subs.valid = false
420 subs.mutex.Unlock()
421 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
422 } else {
423 subs.mutex.Unlock()
424 }
Juha Hyttinen429cfe62020-03-31 11:23:02 +0300425 //Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
426 // If parallel deletes ongoing both might pass earlier sendE2TSubscriptionDeleteRequest(...) if
427 // RemoveFromSubscription locates in caller side (now in handleXAPPSubscriptionDeleteRequest(...))
428 c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
Juha Hyttinen47942b42020-02-27 10:41:43 +0200429 parentTrans.SendEvent(nil, 0)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200430}
431
432//-------------------------------------------------------------------
433// send to E2T Subscription Request
434//-------------------------------------------------------------------
Juha Hyttinen83ada002020-01-30 10:36:33 +0200435func (c *Control) sendE2TSubscriptionRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp) interface{} {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200436 var err error
437 var event interface{} = nil
438 var timedOut bool = false
439
440 subReqMsg := subs.SubReqMsg
Juha Hyttinen83ada002020-01-30 10:36:33 +0200441 subReqMsg.RequestId = subs.GetReqId().RequestId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200442 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(subReqMsg)
443 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200444 xapp.Logger.Error("SUBS-SubReq: %s", idstring(err, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200445 return event
446 }
447
448 for retries := uint64(0); retries < e2tMaxSubReqTryCount; retries++ {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200449 desc := fmt.Sprintf("(retry %d)", retries)
450 c.rmrSendToE2T(desc, subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200451 event, timedOut = trans.WaitEvent(e2tSubReqTimeout)
452 if timedOut {
453 continue
454 }
455 break
456 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200457 xapp.Logger.Debug("SUBS-SubReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200458 return event
459}
460
461//-------------------------------------------------------------------
462// send to E2T Subscription Delete Request
463//-------------------------------------------------------------------
464
Juha Hyttinen83ada002020-01-30 10:36:33 +0200465func (c *Control) sendE2TSubscriptionDeleteRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp) interface{} {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200466 var err error
467 var event interface{}
468 var timedOut bool
469
470 subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
Juha Hyttinen83ada002020-01-30 10:36:33 +0200471 subDelReqMsg.RequestId = subs.GetReqId().RequestId
Juha Hyttinenaf91f972020-01-24 08:38:47 +0200472 subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
Juha Hyttinen422d0182020-01-17 13:37:05 +0200473 trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
474 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200475 xapp.Logger.Error("SUBS-SubDelReq: %s", idstring(err, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200476 return event
477 }
478
479 for retries := uint64(0); retries < e2tMaxSubDelReqTryCount; retries++ {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200480 desc := fmt.Sprintf("(retry %d)", retries)
481 c.rmrSendToE2T(desc, subs, trans)
Juha Hyttinen422d0182020-01-17 13:37:05 +0200482 event, timedOut = trans.WaitEvent(e2tSubDelReqTime)
483 if timedOut {
484 continue
485 }
486 break
487 }
Juha Hyttinen83ada002020-01-30 10:36:33 +0200488 xapp.Logger.Debug("SUBS-SubDelReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200489 return event
490}
491
492//-------------------------------------------------------------------
493// handle from E2T Subscription Reponse
494//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300495func (c *Control) handleE2TSubscriptionResponse(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200496 xapp.Logger.Info("MSG from E2T: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200497 subRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
498 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200499 xapp.Logger.Error("MSG-SubResp %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200500 return
501 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300502 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subRespMsg.RequestId.InstanceId})
Juha Hyttinen422d0182020-01-17 13:37:05 +0200503 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200504 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params))
Juha Hyttinen422d0182020-01-17 13:37:05 +0200505 return
Juha Hyttinen31797b42020-01-16 14:05:01 +0200506 }
507 trans := subs.GetTransaction()
508 if trans == nil {
Juha Hyttinen422d0182020-01-17 13:37:05 +0200509 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200510 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params, subs))
Juha Hyttinenff8dccd2019-12-10 14:34:07 +0200511 return
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200512 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200513 sendOk, timedOut := trans.SendEvent(subRespMsg, e2tRecvMsgTimeout)
514 if sendOk == false {
515 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200516 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, trans, subs))
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000517 }
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000518 return
kalnagy45114752019-06-18 14:40:39 +0200519}
520
Juha Hyttinen422d0182020-01-17 13:37:05 +0200521//-------------------------------------------------------------------
522// handle from E2T Subscription Failure
523//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300524func (c *Control) handleE2TSubscriptionFailure(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200525 xapp.Logger.Info("MSG from E2T: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200526 subFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000527 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200528 xapp.Logger.Error("MSG-SubFail %s", idstring(err, params))
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000529 return
530 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300531 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subFailMsg.RequestId.InstanceId})
Juha Hyttinen31797b42020-01-16 14:05:01 +0200532 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200533 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params))
Juha Hyttinenaafee7f2020-01-14 14:54:51 +0200534 return
535 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200536 trans := subs.GetTransaction()
537 if trans == nil {
538 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200539 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200540 return
541 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200542 sendOk, timedOut := trans.SendEvent(subFailMsg, e2tRecvMsgTimeout)
543 if sendOk == false {
544 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200545 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, trans, subs))
Juha Hyttinenaafee7f2020-01-14 14:54:51 +0200546 }
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200547 return
548}
549
Juha Hyttinen422d0182020-01-17 13:37:05 +0200550//-------------------------------------------------------------------
551// handle from E2T Subscription Delete Response
552//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300553func (c *Control) handleE2TSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200554 xapp.Logger.Info("MSG from E2T: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200555 subDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload)
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200556 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200557 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200558 return
559 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300560 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelRespMsg.RequestId.InstanceId})
Juha Hyttinen31797b42020-01-16 14:05:01 +0200561 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200562 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
Juha Hyttinen0d064ec2020-01-09 09:08:53 +0200563 return
564 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200565 trans := subs.GetTransaction()
566 if trans == nil {
567 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200568 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200569 return
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200570 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200571 sendOk, timedOut := trans.SendEvent(subDelRespMsg, e2tRecvMsgTimeout)
572 if sendOk == false {
573 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200574 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, trans, subs))
Juha Hyttinen60bfcf92020-01-14 15:14:24 +0200575 }
Anssi Mannila2e99e2f2019-12-05 13:57:06 +0200576 return
577}
578
Juha Hyttinen422d0182020-01-17 13:37:05 +0200579//-------------------------------------------------------------------
580// handle from E2T Subscription Delete Failure
581//-------------------------------------------------------------------
Juha Hyttinen9dc5adc2020-08-13 10:02:40 +0300582func (c *Control) handleE2TSubscriptionDeleteFailure(params *xapp.RMRParams) {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200583 xapp.Logger.Info("MSG from E2T: %s", params.String())
Juha Hyttinen422d0182020-01-17 13:37:05 +0200584 subDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload)
Juha Hyttinen31797b42020-01-16 14:05:01 +0200585 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200586 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
Anssi Mannilaf1d0eb62019-12-17 15:29:55 +0200587 return
588 }
Juha Hyttinenaada6452020-04-07 08:47:58 +0300589 subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelFailMsg.RequestId.InstanceId})
Anssi Mannila8046c702020-01-02 13:39:05 +0200590 if err != nil {
Juha Hyttinen83ada002020-01-30 10:36:33 +0200591 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
Anssi Mannila8046c702020-01-02 13:39:05 +0200592 return
593 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200594 trans := subs.GetTransaction()
595 if trans == nil {
596 err = fmt.Errorf("Ongoing transaction not found")
Juha Hyttinen83ada002020-01-30 10:36:33 +0200597 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params, subs))
Juha Hyttinen86a46202020-01-14 12:49:09 +0200598 return
599 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200600 sendOk, timedOut := trans.SendEvent(subDelFailMsg, e2tRecvMsgTimeout)
601 if sendOk == false {
602 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
Juha Hyttinen83ada002020-01-30 10:36:33 +0200603 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, trans, subs))
Anssi Mannila8046c702020-01-02 13:39:05 +0200604 }
kalnagy93cc3e22019-09-19 11:29:29 +0200605 return
606}
607
Juha Hyttinen422d0182020-01-17 13:37:05 +0200608//-------------------------------------------------------------------
609//
610//-------------------------------------------------------------------
611func typeofSubsMessage(v interface{}) string {
612 if v == nil {
613 return "NIL"
kalnagy93cc3e22019-09-19 11:29:29 +0200614 }
Juha Hyttinen422d0182020-01-17 13:37:05 +0200615 switch v.(type) {
616 case *e2ap.E2APSubscriptionRequest:
617 return "SubReq"
618 case *e2ap.E2APSubscriptionResponse:
619 return "SubResp"
620 case *e2ap.E2APSubscriptionFailure:
621 return "SubFail"
622 case *e2ap.E2APSubscriptionDeleteRequest:
623 return "SubDelReq"
624 case *e2ap.E2APSubscriptionDeleteResponse:
625 return "SubDelResp"
626 case *e2ap.E2APSubscriptionDeleteFailure:
627 return "SubDelFail"
628 default:
629 return "Unknown"
Juha Hyttinen31797b42020-01-16 14:05:01 +0200630 }
Anssi Mannilaf1d0eb62019-12-17 15:29:55 +0200631}