Fix for subscription fail handling
[ric-plt/submgr.git] / pkg / control / sdl.go
1 /*
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
20 package control
21
22 import (
23         "encoding/json"
24         "fmt"
25         "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
26         sdl "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
27         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
28         "strconv"
29 )
30
31 type SubscriptionInfo struct {
32         Valid       bool
33         ReqId       RequestId
34         Meid        xapp.RMRMeid
35         EpList      xapp.RmrEndpointList
36         SubReqMsg   e2ap.E2APSubscriptionRequest
37         SubRespMsg  e2ap.E2APSubscriptionResponse
38         SubRespRcvd string
39 }
40
41 func CreateSdl() Sdlnterface {
42         return sdl.NewSdlInstance("submgr", sdl.NewDatabase())
43 }
44
45 func (c *Control) WriteSubscriptionToSdl(subId uint32, subs *Subscription) error {
46
47         var subscriptionInfo SubscriptionInfo
48         subscriptionInfo.Valid = subs.valid
49         subscriptionInfo.ReqId = subs.ReqId
50         subscriptionInfo.Meid = *subs.Meid
51         subscriptionInfo.EpList = subs.EpList
52         subscriptionInfo.SubReqMsg = *subs.SubReqMsg
53
54         if typeofSubsMessage(subs.SubRFMsg) == "SubResp" {
55                 subscriptionInfo.SubRespRcvd = "SubResp"
56                 subscriptionInfo.SubRespMsg = *subs.SubRFMsg.(*e2ap.E2APSubscriptionResponse)
57         } else {
58                 subscriptionInfo.SubRespRcvd = ""
59         }
60
61         jsonData, err := json.Marshal(subscriptionInfo)
62         if err != nil {
63                 return fmt.Errorf("SDL: WriteSubscriptionToSdl() json.Marshal error: %s", err.Error())
64         }
65
66         if err = c.db.Set(strconv.FormatUint(uint64(subId), 10), jsonData); err != nil {
67                 c.UpdateCounter(cSDLWriteFailure)
68                 return fmt.Errorf("SDL: WriteSubscriptionToSdl(): %s", err.Error())
69         } else {
70                 xapp.Logger.Debug("SDL: Subscription written in db. subId = %v", subId)
71         }
72         return nil
73 }
74
75 func (c *Control) ReadSubscriptionFromSdl(subId uint32) (*Subscription, error) {
76
77         // This function is now just for testing purpose
78         key := strconv.FormatUint(uint64(subId), 10)
79         retMap, err := c.db.Get([]string{key})
80         if err != nil {
81                 c.UpdateCounter(cSDLReadFailure)
82                 return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl(): %s", err.Error())
83         } else {
84                 xapp.Logger.Debug("SDL: Subscription read from db.  subId = %v", subId)
85         }
86
87         subs := &Subscription{}
88         for _, iSubscriptionInfo := range retMap {
89
90                 if iSubscriptionInfo == nil {
91                         return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl() subscription not found. subId = %v\n", subId)
92                 }
93
94                 subscriptionInfo := &SubscriptionInfo{}
95                 jsonSubscriptionInfo := iSubscriptionInfo.(string)
96
97                 if err := json.Unmarshal([]byte(jsonSubscriptionInfo), subscriptionInfo); err != nil {
98                         return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl() json.unmarshal error: %s\n", err.Error())
99                 }
100
101                 subs = c.CreateSubscription(subscriptionInfo, &jsonSubscriptionInfo)
102         }
103         return subs, nil
104 }
105
106 func (c *Control) CreateSubscription(subscriptionInfo *SubscriptionInfo, jsonSubscriptionInfo *string) *Subscription {
107
108         subs := &Subscription{}
109         subs.registry = c.registry
110         subs.valid = subscriptionInfo.Valid
111         subs.ReqId = subscriptionInfo.ReqId
112         meid := xapp.RMRMeid{}
113         meid = subscriptionInfo.Meid
114         subs.Meid = &meid
115         subs.EpList = subscriptionInfo.EpList
116         subs.TheTrans = nil
117         subReq := e2ap.E2APSubscriptionRequest{}
118         subReq = subscriptionInfo.SubReqMsg
119         subs.SubReqMsg = &subReq
120
121         if subscriptionInfo.SubRespRcvd == "SubResp" {
122                 subs.SubRespRcvd = true
123                 subResp := e2ap.E2APSubscriptionResponse{}
124                 subResp = subscriptionInfo.SubRespMsg
125                 subs.SubRFMsg = &subResp
126         } else {
127                 subs.SubRespRcvd = false
128                 subs.SubRFMsg = nil
129                 xapp.Logger.Debug("SDL: CreateSubscription() subscriptionInfo.SubRespRcvd == '', InstanceId=%v ", subscriptionInfo.ReqId.InstanceId)
130         }
131         return subs
132 }
133
134 func (c *Control) RemoveSubscriptionFromSdl(subId uint32) error {
135
136         key := strconv.FormatUint(uint64(subId), 10)
137         if err := c.db.Remove([]string{key}); err != nil {
138                 return fmt.Errorf("SDL: RemoveSubscriptionfromSdl(): %s\n", err.Error())
139         } else {
140                 xapp.Logger.Debug("SDL: Subscription removed from db. subId = %v", subId)
141         }
142         return nil
143 }
144
145 func (c *Control) ReadAllSubscriptionsFromSdl() ([]uint32, map[uint32]*Subscription, error) {
146
147         // Read all subscriptionInfos
148         var subIds []uint32
149         var i uint32
150         for i = 1; i < 65535; i++ {
151                 subIds = append(subIds, i)
152         }
153
154         retMap := make(map[uint32]*Subscription)
155         // Get all keys
156         keys, err := c.db.GetAll()
157         if err != nil {
158                 c.UpdateCounter(cSDLReadFailure)
159                 return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), GetAll(). Error while reading keys from DBAAS %s\n", err.Error())
160         }
161
162         if len(keys) == 0 {
163                 return subIds, retMap, nil
164         }
165
166         // Get all subscriptionInfos
167         iSubscriptionMap, err := c.db.Get(keys)
168         if err != nil {
169                 c.UpdateCounter(cSDLReadFailure)
170                 return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), Get():  Error while reading subscriptions from DBAAS %s\n", err.Error())
171         }
172
173         for _, iSubscriptionInfo := range iSubscriptionMap {
174
175                 if iSubscriptionInfo == nil {
176                         return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() iSubscriptionInfo = nil\n")
177                 }
178
179                 subscriptionInfo := &SubscriptionInfo{}
180                 jsonSubscriptionInfo := iSubscriptionInfo.(string)
181
182                 if err := json.Unmarshal([]byte(jsonSubscriptionInfo), subscriptionInfo); err != nil {
183                         return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() json.unmarshal error: %s\n", err.Error())
184                 }
185
186                 subs := c.CreateSubscription(subscriptionInfo, &jsonSubscriptionInfo)
187
188                 if int(subscriptionInfo.ReqId.InstanceId) >= len(subIds) {
189                         return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() index is out of range. Index is %d with slice length %d", subscriptionInfo.ReqId.InstanceId, len(subIds))
190                 }
191                 retMap[subscriptionInfo.ReqId.InstanceId] = subs
192
193                 // Remove subId from free subIds. Original slice is modified here!
194                 if subIds, err = removeNumber(subIds, subscriptionInfo.ReqId.InstanceId); err != nil {
195                         return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() error: %s\n", err.Error())
196                 }
197         }
198         return subIds, retMap, nil
199 }
200
201 func removeNumber(s []uint32, removedNum uint32) ([]uint32, error) {
202         for i, num := range s {
203                 if removedNum == uint32(num) {
204                         s = append(s[:i], s[i+1:]...)
205                         return s[:len(s)], nil
206                 }
207         }
208         return nil, fmt.Errorf("SDL: To be removed number not in the slice. removedNum: %v", removedNum)
209 }
210 func (c *Control) RemoveAllSubscriptionsFromSdl() error {
211
212         if err := c.db.RemoveAll(); err != nil {
213                 c.UpdateCounter(cSDLRemoveFailure)
214                 return fmt.Errorf("SDL: RemoveAllSubscriptionsFromSdl(): %s\n", err.Error())
215         } else {
216                 xapp.Logger.Debug("SDL: All subscriptions removed from db")
217         }
218         return nil
219 }