2 * Copyright 2020 Intel Corporation, Inc
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/contextdb"
26 pkgerrors "github.com/pkg/errors"
29 const maxrand = 0x7fffffffffffffff
30 const prefix string = "/context/"
32 type RunTimeContext struct {
37 type Rtcontext interface {
38 RtcInit() (interface{}, error)
39 RtcLoad(interface{}) (interface{}, error)
40 RtcCreate() (interface{}, error)
41 RtcAddMeta(meta interface{}) error
42 RtcGet() (interface{}, error)
43 RtcAddLevel(handle interface{}, level string, value string) (interface{}, error)
44 RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error)
45 RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error)
46 RtcDeletePair(handle interface{}) error
47 RtcDeletePrefix(handle interface{}) error
48 RtcGetHandles(handle interface{}) ([]interface{}, error)
49 RtcGetValue(handle interface{}, value interface{}) error
50 RtcUpdateValue(handle interface{}, value interface{}) error
51 RtcGetMeta() (interface{}, error)
52 RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error)
55 //Intialize context by assiging a new id
56 func (rtc *RunTimeContext) RtcInit() (interface{}, error) {
58 return nil, pkgerrors.Errorf("Error, context already initialized")
60 ra := rand.New(rand.NewSource(time.Now().UnixNano()))
61 rn := ra.Int63n(maxrand)
62 id := fmt.Sprintf("%v", rn)
63 cid := (prefix + id + "/")
64 rtc.cid = interface{}(cid)
65 return interface{}(id), nil
69 //Load context using the given id
70 func (rtc *RunTimeContext) RtcLoad(id interface{}) (interface{}, error) {
71 str := fmt.Sprintf("%v", id)
73 return nil, pkgerrors.Errorf("Not a valid context id")
75 cid := (prefix + str + "/")
76 rtc.cid = interface{}(cid)
77 handle, err := rtc.RtcGet()
79 return nil, pkgerrors.Errorf("Error finding the context id: %s", err.Error())
84 func (rtc *RunTimeContext) RtcCreate() (interface{}, error) {
85 cid := fmt.Sprintf("%v", rtc.cid)
87 return nil, pkgerrors.Errorf("Error, context not intialized")
89 if !strings.HasPrefix(cid, prefix) {
90 return nil, pkgerrors.Errorf("Not a valid run time context prefix")
92 id := strings.SplitN(cid, "/", 4)[2]
93 err := contextdb.Db.Put(cid, id)
95 return nil, pkgerrors.Errorf("Error creating run time context: %s", err.Error())
101 //RtcAddMeta is used for saving meta data of appContext into ETCD.
102 func (rtc *RunTimeContext) RtcAddMeta(meta interface{}) error {
103 cid := fmt.Sprintf("%v", rtc.cid)
105 return pkgerrors.Errorf("Error, context not intialized")
107 if !strings.HasPrefix(cid, prefix) {
108 return pkgerrors.Errorf("Not a valid run time context prefix")
112 k := cid + "meta" + "/"
113 err := contextdb.Db.Put(k, rtc.meta)
115 return pkgerrors.Errorf("Error saving metadata in run time context: %s", err.Error())
121 //Get the root handle
122 func (rtc *RunTimeContext) RtcGet() (interface{}, error) {
123 str := fmt.Sprintf("%v", rtc.cid)
124 if !strings.HasPrefix(str, prefix) {
125 return nil, pkgerrors.Errorf("Not a valid run time context")
129 err := contextdb.Db.Get(str, &value)
131 return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())
133 if !strings.Contains(str, value) {
134 return nil, pkgerrors.Errorf("Error matching run time context metadata")
140 // RtcGetMeta method fetches the meta data of the rtc object and returns it.
141 func (rtc *RunTimeContext) RtcGetMeta() (interface{}, error) {
142 str := fmt.Sprintf("%v", rtc.cid)
143 if !strings.HasPrefix(str, prefix) {
144 return nil, pkgerrors.Errorf("Not a valid run time context")
147 var value interface{}
148 k := str + "meta" + "/"
149 err := contextdb.Db.Get(k, &value)
151 return nil, pkgerrors.Errorf("Error getting run time context metadata: %s", err.Error())
157 //Add a new level at a given handle and return the new handle
158 func (rtc *RunTimeContext) RtcAddLevel(handle interface{}, level string, value string) (interface{}, error) {
159 str := fmt.Sprintf("%v", handle)
160 sid := fmt.Sprintf("%v", rtc.cid)
161 if !strings.HasPrefix(str, sid) {
162 return nil, pkgerrors.Errorf("Not a valid run time context handle")
166 return nil, pkgerrors.Errorf("Not a valid run time context level")
169 return nil, pkgerrors.Errorf("Not a valid run time context level value")
172 key := str + level + "/" + value + "/"
173 err := contextdb.Db.Put(key, value)
175 return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())
178 return (interface{})(key), nil
181 // RtcAddOneLevel adds one more level to the existing context prefix.RtcAddOneLevel. It takes in PreviousContentLevel as inteface, new level to be appended as string and the value to be saved of any type. It returns the updated interface and nil if no error.
183 func (rtc *RunTimeContext) RtcAddOneLevel(pl interface{}, level string, value interface{}) (interface{}, error) {
184 str := fmt.Sprintf("%v", pl)
185 sid := fmt.Sprintf("%v", rtc.cid)
186 if !strings.HasPrefix(str, sid) {
187 return nil, pkgerrors.Errorf("Not a valid run time context handle")
191 return nil, pkgerrors.Errorf("Not a valid run time context level")
194 return nil, pkgerrors.Errorf("Not a valid run time context level value")
197 key := str + level + "/"
198 err := contextdb.Db.Put(key, value)
200 return nil, pkgerrors.Errorf("Error adding run time context level: %s", err.Error())
202 return (interface{})(key), nil
205 // Add a resource under the given level and return new handle
206 func (rtc *RunTimeContext) RtcAddResource(handle interface{}, resname string, value interface{}) (interface{}, error) {
208 str := fmt.Sprintf("%v", handle)
209 sid := fmt.Sprintf("%v", rtc.cid)
210 if !strings.HasPrefix(str, sid) {
211 return nil, pkgerrors.Errorf("Not a valid run time context handle")
214 return nil, pkgerrors.Errorf("Not a valid run time context resource name")
217 return nil, pkgerrors.Errorf("Not a valid run time context resource value")
220 k := str + "resource" + "/" + resname + "/"
221 err := contextdb.Db.Put(k, value)
223 return nil, pkgerrors.Errorf("Error adding run time context resource: %s", err.Error())
225 return (interface{})(k), nil
228 // Add instruction at a given level and type, return the new handle
229 func (rtc *RunTimeContext) RtcAddInstruction(handle interface{}, level string, insttype string, value interface{}) (interface{}, error) {
230 str := fmt.Sprintf("%v", handle)
231 sid := fmt.Sprintf("%v", rtc.cid)
232 if !strings.HasPrefix(str, sid) {
233 return nil, pkgerrors.Errorf("Not a valid run time context handle")
237 return nil, pkgerrors.Errorf("Not a valid run time context level")
240 return nil, pkgerrors.Errorf("Not a valid run time context instruction type")
243 return nil, pkgerrors.Errorf("Not a valid run time context instruction value")
245 k := str + level + "/" + "instruction" + "/" + insttype + "/"
246 err := contextdb.Db.Put(k, fmt.Sprintf("%v", value))
248 return nil, pkgerrors.Errorf("Error adding run time context instruction: %s", err.Error())
251 return (interface{})(k), nil
254 //Delete the key value pair using given handle
255 func (rtc *RunTimeContext) RtcDeletePair(handle interface{}) error {
256 str := fmt.Sprintf("%v", handle)
257 sid := fmt.Sprintf("%v", rtc.cid)
258 if !strings.HasPrefix(str, sid) {
259 return pkgerrors.Errorf("Not a valid run time context handle")
261 err := contextdb.Db.Delete(str)
263 return pkgerrors.Errorf("Error deleting run time context pair: %s", err.Error())
269 // Delete all handles underneath the given handle
270 func (rtc *RunTimeContext) RtcDeletePrefix(handle interface{}) error {
271 str := fmt.Sprintf("%v", handle)
272 sid := fmt.Sprintf("%v", rtc.cid)
273 if !strings.HasPrefix(str, sid) {
274 return pkgerrors.Errorf("Not a valid run time context handle")
277 err := contextdb.Db.DeleteAll(str)
279 return pkgerrors.Errorf("Error deleting run time context with prefix: %s", err.Error())
285 // Return the list of handles under the given handle
286 func (rtc *RunTimeContext) RtcGetHandles(handle interface{}) ([]interface{}, error) {
287 str := fmt.Sprintf("%v", handle)
288 sid := fmt.Sprintf("%v", rtc.cid)
289 if !strings.HasPrefix(str, sid) {
290 return nil, pkgerrors.Errorf("Not a valid run time context handle")
293 s, err := contextdb.Db.GetAllKeys(str)
295 return nil, pkgerrors.Errorf("Error getting run time context handles: %s", err.Error())
297 r := make([]interface{}, len(s))
298 for i, v := range s {
304 // Get the value for a given handle
305 func (rtc *RunTimeContext) RtcGetValue(handle interface{}, value interface{}) error {
306 str := fmt.Sprintf("%v", handle)
307 sid := fmt.Sprintf("%v", rtc.cid)
308 if !strings.HasPrefix(str, sid) {
309 return pkgerrors.Errorf("Not a valid run time context handle")
312 err := contextdb.Db.Get(str, value)
314 return pkgerrors.Errorf("Error getting run time context value: %s", err.Error())
320 // Update the value of a given handle
321 func (rtc *RunTimeContext) RtcUpdateValue(handle interface{}, value interface{}) error {
322 str := fmt.Sprintf("%v", handle)
323 sid := fmt.Sprintf("%v", rtc.cid)
324 if !strings.HasPrefix(str, sid) {
325 return pkgerrors.Errorf("Not a valid run time context handle")
327 err := contextdb.Db.Put(str, value)
329 return pkgerrors.Errorf("Error updating run time context value: %s", err.Error())