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