Add init and reinit interfaces to context libs
[multicloud/k8s.git] / src / orchestrator / pkg / rtcontext / rtcontext.go
1 /*
2  * Copyright 2020 Intel Corporation, Inc
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package rtcontext
18
19 import (
20         "fmt"
21         "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/contextdb"
22         pkgerrors "github.com/pkg/errors"
23         "math/rand"
24         "strings"
25         "time"
26 )
27
28 const maxrand = 0x7fffffffffffffff
29 const prefix string = "/context/"
30
31 type RunTimeContext struct {
32         cid interface{}
33 }
34
35 type Rtcontext interface {
36         RtcInit() (interface{}, error)
37         RtcLoad(interface{}) (interface{}, error)
38         RtcCreate() (interface{}, error)
39         RtcGet() (interface{}, error)
40         RtcAddLevel(handle interface{}, level string, value string) (interface{}, error)
41         RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error)
42         RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error)
43         RtcDeletePair(handle interface{}) error
44         RtcDeletePrefix(handle interface{}) error
45         RtcGetHandles(handle interface{}) ([]interface{}, error)
46         RtcGetValue(handle interface{}, value interface{}) error
47         RtcUpdateValue(handle interface{}, value interface{}) error
48 }
49
50 //Intialize context by assiging a new id
51 func (rtc *RunTimeContext) RtcInit() (interface{}, error) {
52         if rtc.cid != nil {
53                 return nil, pkgerrors.Errorf("Error, context already initialized")
54         }
55         ra := rand.New(rand.NewSource(time.Now().UnixNano()))
56         rn := ra.Int63n(maxrand)
57         id := fmt.Sprintf("%v", rn)
58         cid := (prefix + id + "/")
59         rtc.cid = interface{}(cid)
60         return interface{}(id), nil
61
62 }
63
64 //Load context using the given id
65 func (rtc *RunTimeContext) RtcLoad(id interface{}) (interface{}, error) {
66         str := fmt.Sprintf("%v", id)
67         if str == "" {
68                 return nil, pkgerrors.Errorf("Not a valid context id")
69         }
70         cid := (prefix + str + "/")
71         rtc.cid = interface{}(cid)
72         handle, err := rtc.RtcGet()
73         if err != nil {
74                 return nil, pkgerrors.Errorf("Error finding the context id: %s", err.Error())
75         }
76         return handle, nil
77 }
78
79 //Create context using the id and prefix
80 func (rtc *RunTimeContext) RtcCreate() (interface{}, error) {
81         cid := fmt.Sprintf("%v", rtc.cid)
82         if cid == "" {
83                 return nil, pkgerrors.Errorf("Error, context not intialized")
84         }
85         if !strings.HasPrefix(cid, prefix) {
86                 return nil, pkgerrors.Errorf("Not a valid run time context prefix")
87         }
88         id := strings.SplitN(cid, "/", 4)[2]
89         err := contextdb.Db.Put(cid, id)
90         if err != nil {
91                 return nil, pkgerrors.Errorf("Error creating run time context: %s", err.Error())
92         }
93
94         return rtc.cid, nil
95 }
96
97 //Get the root handle
98 func (rtc *RunTimeContext) RtcGet() (interface{}, error) {
99         str := fmt.Sprintf("%v", rtc.cid)
100         if !strings.HasPrefix(str, prefix) {
101                 return nil, pkgerrors.Errorf("Not a valid run time context")
102         }
103
104         var value string
105         err := contextdb.Db.Get(str, &value)
106         if err != nil {
107                 return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())
108         }
109         if !strings.Contains(str, value) {
110                 return nil, pkgerrors.Errorf("Error matching run time context metadata")
111         }
112
113         return rtc.cid, nil
114 }
115
116 //Add a new level at a given handle and return the new handle
117 func (rtc *RunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {
118         str := fmt.Sprintf("%v", handle)
119         sid := fmt.Sprintf("%v", rtc.cid)
120         if !strings.HasPrefix(str, sid) {
121                 return nil, pkgerrors.Errorf("Not a valid run time context handle")
122         }
123
124         if level == "" {
125                 return nil, pkgerrors.Errorf("Not a valid run time context level")
126         }
127         if value == "" {
128                 return nil, pkgerrors.Errorf("Not a valid run time context level value")
129         }
130
131         key := str + level + "/" + value + "/"
132         err := contextdb.Db.Put(key, value)
133         if err != nil {
134                 return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())
135         }
136
137         return (interface{})(key), nil
138 }
139
140 // Add a resource under the given level and return new handle
141 func (rtc *RunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {
142
143         str := fmt.Sprintf("%v", handle)
144         sid := fmt.Sprintf("%v", rtc.cid)
145         if !strings.HasPrefix(str, sid) {
146                 return nil, pkgerrors.Errorf("Not a valid run time context handle")
147         }
148         if resname == "" {
149                 return nil, pkgerrors.Errorf("Not a valid run time context resource name")
150         }
151         if value == nil {
152                 return nil, pkgerrors.Errorf("Not a valid run time context resource value")
153         }
154
155         k := str + "resource" + "/" + resname + "/"
156         err := contextdb.Db.Put(k, value)
157         if err != nil {
158                 return nil, pkgerrors.Errorf("Error adding run time context resource: %s", err.Error())
159         }
160         return (interface{})(k), nil
161 }
162
163 // Add instruction at a given level and type, return the new handle
164 func (rtc *RunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {
165         str := fmt.Sprintf("%v", handle)
166         sid := fmt.Sprintf("%v", rtc.cid)
167         if !strings.HasPrefix(str, sid) {
168                 return nil, pkgerrors.Errorf("Not a valid run time context handle")
169         }
170
171         if level == "" {
172                 return nil, pkgerrors.Errorf("Not a valid run time context level")
173         }
174         if insttype == "" {
175                 return nil, pkgerrors.Errorf("Not a valid run time context instruction type")
176         }
177         if value == nil {
178                 return nil, pkgerrors.Errorf("Not a valid run time context instruction value")
179         }
180
181         k := str + level + "/" + "instruction" + "/" + insttype + "/"
182         err := contextdb.Db.Put(k, fmt.Sprintf("%v", value))
183         if err != nil {
184                 return nil, pkgerrors.Errorf("Error adding run time context instruction: %s", err.Error())
185         }
186
187         return (interface{})(k), nil
188 }
189
190 //Delete the key value pair using given handle
191 func (rtc *RunTimeContext) RtcDeletePair(handle interface{}) error {
192         str := fmt.Sprintf("%v", handle)
193         sid := fmt.Sprintf("%v", rtc.cid)
194         if !strings.HasPrefix(str, sid) {
195                 return pkgerrors.Errorf("Not a valid run time context handle")
196         }
197
198         err := contextdb.Db.Delete(str)
199         if err != nil {
200                 return pkgerrors.Errorf("Error deleting run time context pair: %s", err.Error())
201         }
202
203         return nil
204 }
205
206 // Delete all handles underneath the given handle
207 func (rtc *RunTimeContext) RtcDeletePrefix(handle interface{}) error {
208         str := fmt.Sprintf("%v", handle)
209         sid := fmt.Sprintf("%v", rtc.cid)
210         if !strings.HasPrefix(str, sid) {
211                 return pkgerrors.Errorf("Not a valid run time context handle")
212         }
213
214         err := contextdb.Db.DeleteAll(str)
215         if err != nil {
216                 return pkgerrors.Errorf("Error deleting run time context with prefix: %s", err.Error())
217         }
218
219         return nil
220 }
221
222 // Return the list of handles under the given handle
223 func (rtc *RunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {
224         str := fmt.Sprintf("%v", handle)
225         sid := fmt.Sprintf("%v", rtc.cid)
226         if !strings.HasPrefix(str, sid) {
227                 return nil, pkgerrors.Errorf("Not a valid run time context handle")
228         }
229
230         s, err := contextdb.Db.GetAllKeys(str)
231         if err != nil {
232                 return nil, pkgerrors.Errorf("Error getting run time context handles: %s", err.Error())
233         }
234         r := make([]interface{}, len(s))
235         for i, v := range s {
236                 r[i] = v
237         }
238         return r, nil
239 }
240
241 // Get the value for a given handle
242 func (rtc *RunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {
243         str := fmt.Sprintf("%v", handle)
244         sid := fmt.Sprintf("%v", rtc.cid)
245         if !strings.HasPrefix(str, sid) {
246                 return pkgerrors.Errorf("Not a valid run time context handle")
247         }
248
249         err := contextdb.Db.Get(str, value)
250         if err != nil {
251                 return pkgerrors.Errorf("Error getting run time context value: %s", err.Error())
252         }
253
254         return nil
255 }
256
257 // Update the value of a given handle
258 func (rtc *RunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {
259         str := fmt.Sprintf("%v", handle)
260         sid := fmt.Sprintf("%v", rtc.cid)
261         if !strings.HasPrefix(str, sid) {
262                 return pkgerrors.Errorf("Not a valid run time context handle")
263         }
264         err := contextdb.Db.Put(str, value)
265         if err != nil {
266                 return pkgerrors.Errorf("Error updating run time context value: %s", err.Error())
267         }
268         return nil
269
270 }