2 ==================================================================================
3 Copyright (c) 2021 Samsung
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
17 This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 platform project (RICP).
19 ==================================================================================
30 "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1"
31 "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models"
32 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
34 "github.com/santhosh-tekuri/jsonschema/v5"
39 a1PolicyPrefix = "a1.policy_type."
40 a1MediatorNs = "A1m_ns"
41 a1InstancePrefix = "a1.policy_instance."
44 var typeAlreadyError = errors.New("Policy Type already exists")
45 var InstanceAlreadyError = errors.New("Policy Instance already exists")
46 var typeMismatchError = errors.New("Policytype Mismatch")
47 var invalidJsonSchema = errors.New("Invalid Json ")
48 var policyInstanceNotFoundError = errors.New("Policy Instance Not Found")
49 var policyTypeNotFoundError = errors.New("Policy Type Not Found")
51 func (rh *Resthook) IsPolicyTypePresent(err error) bool {
52 return err == policyTypeNotFoundError
55 func (rh *Resthook) IsPolicyInstanceNotFound(err error) bool {
56 return err == policyInstanceNotFoundError
59 func (rh *Resthook) IsTypeAlready(err error) bool {
60 return err == typeAlreadyError
62 func (rh *Resthook) IsInstanceAlready(err error) bool {
63 return err == InstanceAlreadyError
65 func (rh *Resthook) IsTypeMismatch(err error) bool {
66 return err == typeMismatchError
69 func (rh *Resthook) IsValidJson(err error) bool {
70 return err == invalidJsonSchema
72 func NewResthook() *Resthook {
73 return createResthook(sdlgo.NewSyncStorage())
76 func createResthook(sdlInst iSdl) *Resthook {
82 func (rh *Resthook) GetAllPolicyType() []models.PolicyTypeID {
84 var policyTypeIDs []models.PolicyTypeID
86 keys, err := rh.db.GetAll("A1m_ns")
89 a1.Logger.Error("error in retrieving policy. err: %v", err)
92 a1.Logger.Debug("keys : %+v", keys)
94 for _, key := range keys {
95 if strings.HasPrefix(strings.TrimLeft(key, " "), a1PolicyPrefix) {
96 pti := strings.Split(strings.Trim(key, " "), a1PolicyPrefix)[1]
97 ptii, _ := strconv.ParseInt(pti, 10, 64)
98 policyTypeIDs = append(policyTypeIDs, models.PolicyTypeID(ptii))
102 a1.Logger.Debug("return : %+v", policyTypeIDs)
106 func (rh *Resthook) GetPolicyType(policyTypeId models.PolicyTypeID) *models.PolicyTypeSchema {
107 a1.Logger.Debug("GetPolicyType1")
109 var policytypeschema *models.PolicyTypeSchema
112 key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
115 a1.Logger.Debug("key : %+v", key)
117 valmap, err := rh.db.Get(a1MediatorNs, keys[:])
119 a1.Logger.Debug("policytype map : ", valmap)
121 if len(valmap) == 0 {
122 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
123 return policytypeschema
127 a1.Logger.Error("error in retrieving policy type. err: %v", err)
131 if valmap[key] == nil {
132 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
133 return policytypeschema
136 a1.Logger.Debug("keysmap : %+v", valmap[key])
138 var item models.PolicyTypeSchema
139 valStr := fmt.Sprint(valmap[key])
141 a1.Logger.Debug("Policy type for %+v : %+v", key, valStr)
142 valkey := "`" + valStr + "`"
143 valToUnmarshall, err := strconv.Unquote(valkey)
145 a1.Logger.Error("unquote error : %+v", err)
149 a1.Logger.Debug("Policy type for %+v : %+v", key, string(valToUnmarshall))
151 errunm := json.Unmarshal([]byte(valToUnmarshall), &item)
153 a1.Logger.Debug(" Unmarshalled json : %+v", (errunm))
154 a1.Logger.Debug("Policy type Name : %v", (item.Name))
159 func (rh *Resthook) CreatePolicyType(policyTypeId models.PolicyTypeID, httprequest models.PolicyTypeSchema) error {
160 a1.Logger.Debug("CreatePolicyType function")
161 if policyTypeId != models.PolicyTypeID(*httprequest.PolicyTypeID) {
163 a1.Logger.Debug("Policytype Mismatch")
164 return typeMismatchError
166 key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
167 a1.Logger.Debug("key %+v ", key)
168 if data, err := httprequest.MarshalBinary(); err == nil {
169 a1.Logger.Debug("Marshaled String : %+v", string(data))
170 success, err1 := rh.db.SetIfNotExists(a1MediatorNs, key, string(data))
171 a1.Logger.Info("success:%+v", success)
173 a1.Logger.Error("error :%+v", err1)
177 a1.Logger.Debug("Policy type %+v already exist", policyTypeId)
178 return typeAlreadyError
184 func toStringKeys(val interface{}) (interface{}, error) {
186 switch val := val.(type) {
187 case map[interface{}]interface{}:
188 m := make(map[string]interface{})
189 for k, v := range val {
192 return nil, errors.New("found non-string key")
194 m[k], err = toStringKeys(v)
201 var l = make([]interface{}, len(val))
202 for i, v := range val {
203 l[i], err = toStringKeys(v)
214 func validate(httpBodyString string, schemaString string) bool {
216 err := yaml.Unmarshal([]byte(httpBodyString), &m)
218 a1.Logger.Error("Unmarshal error : %+v", err)
220 m, err = toStringKeys(m)
222 a1.Logger.Error("Conversion to string error : %+v", err)
225 compiler := jsonschema.NewCompiler()
226 if err := compiler.AddResource("schema.json", strings.NewReader(schemaString)); err != nil {
227 a1.Logger.Error("string reader error : %+v", err)
230 schema, err := compiler.Compile("schema.json")
232 a1.Logger.Error("schema json compile error : %+v", err)
235 if err := schema.Validate(m); err != nil {
236 a1.Logger.Error("schema validation error : %+v", err)
239 a1.Logger.Debug("validation successfull")
243 func (rh *Resthook) StorePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) (string, error) {
245 operation := "CREATE"
246 typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
249 a1.Logger.Debug("key1 : %+v", typekey)
251 valmap, err := rh.db.Get(a1MediatorNs, keys[:])
253 a1.Logger.Error("policy type error : %+v", err)
255 a1.Logger.Debug("policytype map : %+v", valmap)
256 if valmap[typekey] == nil {
257 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
258 return operation, policyTypeNotFoundError
260 // TODO : rmr creation_timestamp := time.Now() // will be needed for rmr to notify the creation of instance
262 instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
264 instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
266 a1.Logger.Error("policy type error : %v", err)
268 a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
270 if instanceMap[instancekey] != nil {
272 a1.Logger.Debug("UPDATE")
273 data, _ := json.Marshal(httpBody)
274 a1.Logger.Debug("Marshaled String : %+v", string(data))
275 a1.Logger.Debug("key : %+v", instancekey)
276 success, err1 := rh.db.SetIf(a1MediatorNs, instancekey, instanceMap[instancekey], string(data))
278 a1.Logger.Error("error2 :%+v", err1)
279 return operation, err1
282 a1.Logger.Debug("Policy instance %+v already exist", policyInstanceID)
283 return operation, InstanceAlreadyError
286 data, _ := json.Marshal(httpBody)
287 a1.Logger.Debug("Marshaled String : %+v", string(data))
288 a1.Logger.Debug("key : %+v", instancekey)
290 var instance_map []interface{}
291 instance_map = append(instance_map, instancekey, string(data))
292 a1.Logger.Debug("policyinstancetype map : %+v", instance_map[1])
293 a1.Logger.Debug("policyinstancetype to create : %+v", instance_map)
295 err1 := rh.db.Set(a1MediatorNs, instancekey, string(data))
297 a1.Logger.Error("error1 :%+v", err1)
298 return operation, err1
301 a1.Logger.Debug("Policy Instance created ")
302 return operation, nil
306 func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) error {
307 a1.Logger.Debug("CreatePolicyInstance function")
308 // validate the PUT against the schema
309 var policyTypeSchema *models.PolicyTypeSchema
310 policyTypeSchema = rh.GetPolicyType(policyTypeId)
311 schemaStr, err := json.Marshal(policyTypeSchema.CreateSchema)
313 a1.Logger.Error("Json Marshal error : %+v", err)
316 a1.Logger.Debug("schema to validate %+v", string(schemaStr))
317 a1.Logger.Debug("httpbody to validate %+v", httpBody)
318 schemaString := fmt.Sprint(string(schemaStr))
319 httpBodyString := fmt.Sprint((httpBody))
320 isvalid := validate(httpBodyString, schemaString)
323 operation, err = rh.StorePolicyInstance(policyTypeId, policyInstanceID, httpBody)
325 a1.Logger.Error("error :%+v", err)
328 a1.Logger.Debug("policy instance :%+v", operation)
330 a1.Logger.Error("%+v", invalidJsonSchema)
331 return invalidJsonSchema
337 func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (interface{}, error) {
338 a1.Logger.Debug("GetPolicyInstance1")
342 typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
345 a1.Logger.Debug("key1 : %+v", typekey)
347 valmap, err := rh.db.Get(a1MediatorNs, keys[:])
348 if len(valmap) == 0 {
349 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
350 return "{}", policyTypeNotFoundError
354 a1.Logger.Error("error in retrieving policy type. err: %v", err)
358 if valmap[typekey] == nil {
359 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
360 return "{}", policyTypeNotFoundError
363 a1.Logger.Debug("keysmap : %+v", valmap[typekey])
365 instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
366 a1.Logger.Debug("key2 : %+v", instancekey)
367 keys[0] = instancekey
368 instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
370 a1.Logger.Error("policy instance error : %v", err)
372 a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
374 if instanceMap[instancekey] == nil {
375 a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
376 return "{}", policyInstanceNotFoundError
379 valStr := fmt.Sprint(instanceMap[instancekey])
383 func (rh *Resthook) GetAllPolicyInstance(policyTypeId models.PolicyTypeID) []models.PolicyInstanceID ,error {
384 a1.Logger.Debug("GetAllPolicyInstance")
385 var policyTypeInstances = []models.PolicyInstanceID{}
387 keys, err := rh.db.GetAll("A1m_ns")
390 a1.Logger.Error("error in retrieving policy. err: %v", err)
391 return policyTypeInstances ,err
393 a1.Logger.Debug("keys : %+v", keys)
394 typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "."
396 for _, key := range keys {
397 if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) {
398 pti := strings.Split(strings.Trim(key, " "), typekey)[1]
399 a1.Logger.Debug("pti %+v", pti)
400 policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti))
404 if len(policyTypeInstances)==0{
405 a1.Logger.Debug("policy instance Not Present ")
408 a1.Logger.Debug("return : %+v", policyTypeInstances)
409 return policyTypeInstances ,nil