RIC:1060: Change in PTL
[ric-plt/a1.git] / pkg / resthooks / resthooks.go
1 /*
2 ==================================================================================
3
4         Copyright (c) 2021 Samsung
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          This source code is part of the near-RT RIC (RAN Intelligent Controller)
19          platform project (RICP).
20
21 ==================================================================================
22 */
23 package resthooks
24
25 import (
26         "encoding/json"
27         "errors"
28         "fmt"
29         "strconv"
30         "strings"
31         "time"
32
33         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1"
34         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models"
35         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/policy"
36         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/restapi/operations/a1_mediator"
37         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/rmr"
38         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
39         "github.com/santhosh-tekuri/jsonschema/v5"
40         "gopkg.in/yaml.v2"
41 )
42
43 const (
44         a1PolicyPrefix                  = "a1.policy_type."
45         a1MediatorNs                    = "A1m_ns"
46         a1InstancePrefix                = "a1.policy_instance."
47         a1NotificationDestinationPrefix = "a1.policy_notification_destination."
48         a1InstanceMetadataPrefix        = "a1.policy_inst_metadata."
49         a1HandlerPrefix                 = "a1.policy_handler."
50         a1PolicyRequest                 = 20010
51         a1EIDataDelivery                = 20017
52 )
53
54 var typeAlreadyError = errors.New("Policy Type already exists")
55 var InstanceAlreadyError = errors.New("Policy Instance already exists")
56 var typeMismatchError = errors.New("Policytype Mismatch")
57 var invalidJsonSchema = errors.New("Invalid Json ")
58 var policyInstanceNotFoundError = errors.New("Policy Instance Not Found")
59 var policyTypeNotFoundError = errors.New("Policy Type Not Found")
60 var policyTypeCanNotBeDeletedError = errors.New("tried to delete a type that isn't empty")
61 var policyInstanceCanNotBeDeletedError = errors.New("tried to delete a Instance that isn't empty")
62
63 func (rh *Resthook) CanPolicyInstanceBeDeleted(err error) bool {
64         return err == policyInstanceCanNotBeDeletedError
65 }
66
67 func (rh *Resthook) CanPolicyTypeBeDeleted(err error) bool {
68         return err == policyTypeCanNotBeDeletedError
69 }
70
71 func (rh *Resthook) IsPolicyTypeNotFound(err error) bool {
72         return err == policyTypeNotFoundError
73 }
74
75 func (rh *Resthook) IsPolicyInstanceNotFound(err error) bool {
76         return err == policyInstanceNotFoundError
77 }
78
79 func (rh *Resthook) IsTypeAlready(err error) bool {
80         return err == typeAlreadyError
81 }
82 func (rh *Resthook) IsInstanceAlready(err error) bool {
83         return err == InstanceAlreadyError
84 }
85 func (rh *Resthook) IsTypeMismatch(err error) bool {
86         return err == typeMismatchError
87 }
88
89 func (rh *Resthook) IsValidJson(err error) bool {
90         return err == invalidJsonSchema
91 }
92 func NewResthook() *Resthook {
93         sdl := sdlgo.NewSyncStorage()
94         policyManager := policy.NewPolicyManager(sdl)
95         return createResthook(sdl, rmr.NewRMRSender(policyManager))
96 }
97
98 func createResthook(sdlInst iSdl, rmrSenderInst rmr.IRmrSender) *Resthook {
99         rh := &Resthook{
100                 db:             sdlInst,
101                 iRmrSenderInst: rmrSenderInst,
102         }
103
104         return rh
105 }
106
107 func (rh *Resthook) GetA1Health() bool {
108         _, err := rh.db.GetAll("A1m_ns")
109         if err != nil {
110                 a1.Logger.Error("error in connecting to the database. err: %v", err)
111                 return false
112         }
113         a1.Logger.Debug("A1 is healthy")
114         return true
115 }
116
117 func (rh *Resthook) GetAllPolicyType() []models.PolicyTypeID {
118
119         var policyTypeIDs []models.PolicyTypeID
120
121         keys, err := rh.db.GetAll("A1m_ns")
122
123         if err != nil {
124                 a1.Logger.Error("error in retrieving policy. err: %v", err)
125                 return policyTypeIDs
126         }
127         a1.Logger.Debug("keys : %+v", keys)
128
129         for _, key := range keys {
130                 if strings.HasPrefix(strings.TrimLeft(key, " "), a1PolicyPrefix) {
131                         pti := strings.Split(strings.Trim(key, " "), a1PolicyPrefix)[1]
132                         ptii, _ := strconv.ParseInt(pti, 10, 64)
133                         policyTypeIDs = append(policyTypeIDs, models.PolicyTypeID(ptii))
134                 }
135         }
136
137         a1.Logger.Debug("return : %+v", policyTypeIDs)
138         return policyTypeIDs
139 }
140
141 func (rh *Resthook) GetPolicyType(policyTypeId models.PolicyTypeID) (*models.PolicyTypeSchema, error) {
142         a1.Logger.Debug("GetPolicyType1")
143
144         var policytypeschema *models.PolicyTypeSchema
145         var keys [1]string
146
147         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
148         keys[0] = key
149
150         a1.Logger.Debug("key : %+v", key)
151
152         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
153
154         a1.Logger.Debug("policytype map : %+v", valmap)
155
156         if len(valmap) == 0 {
157                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
158                 return policytypeschema, policyTypeNotFoundError
159         }
160
161         if err != nil {
162                 a1.Logger.Error("error in retrieving policy type. err: %v", err)
163                 return nil,policyTypeNotFoundError
164         }
165
166         if valmap[key] == nil {
167                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
168                 return policytypeschema,policyTypeNotFoundError
169         }
170
171         a1.Logger.Debug("keysmap : %+v", valmap[key])
172
173         var item models.PolicyTypeSchema
174         valStr := fmt.Sprint(valmap[key])
175
176         a1.Logger.Debug("Policy type for %+v :  %+v", key, valStr)
177         valkey := "`" + valStr + "`"
178         valToUnmarshall, err := strconv.Unquote(valkey)
179         if err != nil {
180                 a1.Logger.Error("unquote error : %+v", err)
181                 return nil,policyTypeNotFoundError
182         }
183
184         a1.Logger.Debug("Policy type for %+v :  %+v", key, string(valToUnmarshall))
185
186         errunm := json.Unmarshal([]byte(valToUnmarshall), &item)
187
188         a1.Logger.Debug(" Unmarshalled json : %+v", (errunm))
189         a1.Logger.Debug("Policy type Name :  %v", (item.Name))
190
191         return &item,nil
192 }
193
194 func (rh *Resthook) CreatePolicyType(policyTypeId models.PolicyTypeID, httprequest models.PolicyTypeSchema) error {
195         a1.Logger.Debug("CreatePolicyType function")
196         if policyTypeId != models.PolicyTypeID(*httprequest.PolicyTypeID) {
197                 //error message
198                 a1.Logger.Debug("Policytype Mismatch")
199                 return typeMismatchError
200         }
201         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
202         a1.Logger.Debug("key %+v ", key)
203         if data, err := httprequest.MarshalBinary(); err == nil {
204                 a1.Logger.Debug("Marshaled String : %+v", string(data))
205                 success, err1 := rh.db.SetIfNotExists(a1MediatorNs, key, string(data))
206                 a1.Logger.Info("success:%+v", success)
207                 if err1 != nil {
208                         a1.Logger.Error("error :%+v", err1)
209                         return err1
210                 }
211                 if !success {
212                         a1.Logger.Debug("Policy type %+v already exist", policyTypeId)
213                         return typeAlreadyError
214                 }
215         }
216         return nil
217 }
218
219 func toStringKeys(val interface{}) (interface{}, error) {
220         var err error
221         switch val := val.(type) {
222         case map[interface{}]interface{}:
223                 m := make(map[string]interface{})
224                 for k, v := range val {
225                         k, ok := k.(string)
226                         if !ok {
227                                 return nil, errors.New("found non-string key")
228                         }
229                         m[k], err = toStringKeys(v)
230                         if err != nil {
231                                 return nil, err
232                         }
233                 }
234                 return m, nil
235         case []interface{}:
236                 var l = make([]interface{}, len(val))
237                 for i, v := range val {
238                         l[i], err = toStringKeys(v)
239                         if err != nil {
240                                 return nil, err
241                         }
242                 }
243                 return l, nil
244         default:
245                 return val, nil
246         }
247 }
248
249 func validate(httpBodyString string, schemaString string) bool {
250         var m interface{}
251         err := yaml.Unmarshal([]byte(httpBodyString), &m)
252         if err != nil {
253                 a1.Logger.Error("Unmarshal error : %+v", err)
254         }
255         m, err = toStringKeys(m)
256         if err != nil {
257                 a1.Logger.Error("Conversion to string error : %+v", err)
258                 return false
259         }
260         compiler := jsonschema.NewCompiler()
261         if err := compiler.AddResource("schema.json", strings.NewReader(schemaString)); err != nil {
262                 a1.Logger.Error("string reader error : %+v", err)
263                 return false
264         }
265         schema, err := compiler.Compile("schema.json")
266         if err != nil {
267                 a1.Logger.Error("schema json compile error : %+v", err)
268                 return false
269         }
270         if err := schema.Validate(m); err != nil {
271                 a1.Logger.Error("schema validation error : %+v", err)
272                 return false
273         }
274         a1.Logger.Debug("validation successfull")
275         return true
276 }
277
278 func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}, notificationDestination string) (string, error) {
279         var keys [1]string
280         operation := "CREATE"
281         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
282         keys[0] = typekey
283
284         a1.Logger.Debug("key1 : %+v", typekey)
285
286         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
287         if err != nil {
288                 a1.Logger.Error("policy type error : %+v", err)
289         }
290         a1.Logger.Debug("policytype map : %+v", valmap)
291         if valmap[typekey] == nil {
292                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
293                 return operation, policyTypeNotFoundError
294         }
295         // TODO : rmr creation_timestamp := time.Now() // will be needed for rmr to notify the creation of instance
296
297         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
298         notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
299         keys[0] = instancekey
300         instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
301         if err != nil {
302                 a1.Logger.Error("policy type error : %v", err)
303         }
304         a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
305
306         if instanceMap[instancekey] != nil {
307                 operation = "UPDATE"
308                 a1.Logger.Debug("UPDATE")
309                 data, _ := json.Marshal(httpBody)
310                 a1.Logger.Debug("Marshaled String : %+v", string(data))
311                 a1.Logger.Debug("key   : %+v", instancekey)
312                 success, err := rh.db.SetIf(a1MediatorNs, instancekey, instanceMap[instancekey], string(data))
313                 if err != nil {
314                         a1.Logger.Error("error2 :%+v", err)
315                         return operation, err
316                 }
317                 if !success {
318                         a1.Logger.Debug("Policy instance %+v already exist", policyInstanceID)
319                         return operation, InstanceAlreadyError
320                 }
321
322                 if len(notificationDestination) > 0 {
323                         if err = rh.db.Set(a1MediatorNs, notificationDestinationkey, notificationDestination); err != nil {
324                                 a1.Logger.Error("error3 :%+v", err)
325                                 return operation, err
326                         }
327                 }
328         } else {
329                 data, _ := json.Marshal(httpBody)
330                 a1.Logger.Debug("Marshaled String : %+v", string(data))
331                 a1.Logger.Debug("key   : %+v", instancekey)
332
333                 var instance_map []interface{}
334                 instance_map = append(instance_map, instancekey, string(data))
335                 a1.Logger.Debug("policyinstancetype map : %+v", instance_map[1])
336                 a1.Logger.Debug("policyinstancetype to create : %+v", instance_map)
337
338                 if err = rh.db.Set(a1MediatorNs, instancekey, string(data)); err != nil {
339                         a1.Logger.Error("error4 :%+v", err)
340                         return operation, err
341                 }
342                 if len(notificationDestination) > 0 {
343                         if err := rh.db.Set(a1MediatorNs, notificationDestinationkey, notificationDestination); err != nil {
344                                 a1.Logger.Error("error :%+v", err)
345                                 return operation, err
346                         }
347                 }
348         }
349         a1.Logger.Debug("Policy Instance created ")
350         return operation, nil
351 }
352
353 func (rh *Resthook) storePolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) {
354
355         creation_timestamp := time.Now()
356         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
357
358         a1.Logger.Debug("key : %+v", instanceMetadataKey)
359
360         var metadatajson []interface{}
361         metadatajson = append(metadatajson, map[string]string{"created_at": creation_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "False"})
362         metadata, _ := json.Marshal(metadatajson)
363
364         a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(metadata))
365
366         err := rh.db.Set(a1MediatorNs, instanceMetadataKey, string(metadata))
367
368         if err != nil {
369                 a1.Logger.Error("error :%+v", err)
370                 return false, err
371         }
372
373         a1.Logger.Debug("Policy Instance Meta Data created at :%+v", creation_timestamp)
374
375         return true, nil
376 }
377
378 func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}, notificationDestination string) error {
379         a1.Logger.Debug("CreatePolicyInstance function")
380         //  validate the PUT against the schema
381         var policyTypeSchema *models.PolicyTypeSchema
382         policyTypeSchema, err := rh.GetPolicyType(policyTypeId)
383         if err != nil {
384                 a1.Logger.Error("error : %+v", err)
385                 return err
386         }
387         schemaStr, err := json.Marshal(policyTypeSchema.CreateSchema)
388         if err != nil {
389                 a1.Logger.Error("Json Marshal error : %+v", err)
390                 return err
391         }
392         a1.Logger.Debug("schema to validate %+v", string(schemaStr))
393         a1.Logger.Debug("httpbody to validate %+v", httpBody)
394         schemaString := fmt.Sprint(string(schemaStr))
395         httpBodyMarshal, err := json.Marshal(httpBody)
396         httpBodyString := string((httpBodyMarshal))
397         a1.Logger.Debug("schema to validate sprint  %+v", (schemaString))
398         a1.Logger.Debug("httpbody to validate sprint %+v", httpBodyString)
399         isvalid := validate(httpBodyString, schemaString)
400         if isvalid {
401                 var operation string
402                 operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody, notificationDestination)
403                 if err != nil {
404                         a1.Logger.Error("error :%+v", err)
405                         return err
406                 }
407                 a1.Logger.Debug("policy instance :%+v", operation)
408                 iscreated, errmetadata := rh.storePolicyInstanceMetadata(policyTypeId, policyInstanceID)
409                 if errmetadata != nil {
410                         a1.Logger.Error("error :%+v", errmetadata)
411                         return errmetadata
412                 }
413                 if iscreated {
414                         a1.Logger.Debug("policy instance metadata created")
415                 }
416
417                 message := rmr.Message{}
418                 rmrMessage, err := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation)
419                 if err != nil {
420                         a1.Logger.Error("error : %v", err)
421                         return err
422                 }
423                 isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
424                 if isSent {
425                         a1.Logger.Debug("rmrSendToXapp : message sent")
426                 } else {
427                         a1.Logger.Debug("rmrSendToXapp : message not sent")
428                 }
429
430         } else {
431                 a1.Logger.Error("%+v", invalidJsonSchema)
432                 return invalidJsonSchema
433         }
434
435         return nil
436 }
437
438 func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
439         a1.Logger.Debug("GetPolicyInstance1")
440
441         var keys [1]string
442
443         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
444         keys[0] = typekey
445
446         a1.Logger.Debug("key1 : %+v", typekey)
447
448         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
449         if len(valmap) == 0 {
450                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
451                 return map[string]interface{}{}, policyTypeNotFoundError
452         }
453
454         if err != nil {
455                 a1.Logger.Error("error in retrieving policy type. err: %v", err)
456                 return map[string]interface{}{}, err
457         }
458
459         if valmap[typekey] == nil {
460                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
461                 return map[string]interface{}{}, policyTypeNotFoundError
462         }
463
464         a1.Logger.Debug("keysmap : %+v", valmap[typekey])
465
466         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
467         a1.Logger.Debug("key2 : %+v", instancekey)
468         keys[0] = instancekey
469         instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
470         if err != nil {
471                 a1.Logger.Error("policy instance error : %v", err)
472         }
473         a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
474
475         if instanceMap[instancekey] == nil {
476                 a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
477                 return map[string]interface{}{}, policyInstanceNotFoundError
478         }
479
480         var valStr map[string]interface{}
481         err = json.Unmarshal([]byte(instanceMap[instancekey].(string)), &valStr)
482         if err != nil {
483                 fmt.Println("error:", err)
484         }
485         fmt.Println(valStr)
486         return valStr, nil
487 }
488
489 func (rh *Resthook) GetAllPolicyInstance(policyTypeId models.PolicyTypeID) ([]models.PolicyInstanceID, error) {
490         a1.Logger.Debug("GetAllPolicyInstance")
491         var policyTypeInstances = []models.PolicyInstanceID{}
492
493         keys, err := rh.db.GetAll("A1m_ns")
494
495         if err != nil {
496                 a1.Logger.Error("error in retrieving policy. err: %v", err)
497                 return policyTypeInstances, err
498         }
499         a1.Logger.Debug("keys : %+v", keys)
500         typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "."
501
502         for _, key := range keys {
503                 if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) {
504                         pti := strings.Split(strings.Trim(key, " "), typekey)[1]
505                         a1.Logger.Debug("pti %+v", pti)
506                         policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti))
507                 }
508         }
509
510         if len(policyTypeInstances) == 0 {
511                 a1.Logger.Debug("policy instance Not Present  ")
512         }
513
514         a1.Logger.Debug("return : %+v", policyTypeInstances)
515         return policyTypeInstances, nil
516 }
517
518 func (rh *Resthook) DeletePolicyType(policyTypeId models.PolicyTypeID) error {
519         a1.Logger.Debug("DeletePolicyType")
520
521         policyinstances, err := rh.GetAllPolicyInstance(policyTypeId)
522         if err != nil {
523                 a1.Logger.Error("error in retrieving policy. err: %v", err)
524                 return err
525         }
526
527         var keys [1]string
528         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
529         keys[0] = key
530         if len(policyinstances) == 0 {
531                 err := rh.db.Remove(a1MediatorNs, keys[:])
532                 if err != nil {
533                         a1.Logger.Error("error in deleting policy type err: %v", err)
534                         return err
535                 }
536         } else {
537                 a1.Logger.Error("tried to delete a type that isn't empty")
538                 return policyTypeCanNotBeDeletedError
539         }
540         return nil
541 }
542
543 func (rh *Resthook) typeValidity(policyTypeId models.PolicyTypeID) error {
544         var keys [1]string
545
546         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
547         keys[0] = typekey
548
549         a1.Logger.Debug("key1 : %+v", typekey)
550         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
551         if err != nil {
552                 a1.Logger.Error("error in retrieving policytype err: %v", err)
553                 return err
554         }
555         if len(valmap) == 0 {
556                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
557                 return policyTypeNotFoundError
558         }
559         return nil
560 }
561
562 func (rh *Resthook) instanceValidity(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
563         err := rh.typeValidity(policyTypeId)
564         if err != nil {
565                 return err
566         }
567         policyTypeInstances, err := rh.GetPolicyInstance(policyTypeId, policyInstanceID)
568         if err != nil {
569                 a1.Logger.Error("policy instance error : %v", err)
570                 return err
571         }
572         if policyTypeInstances == nil {
573                 a1.Logger.Debug("policy instance Not Present  ")
574                 return policyInstanceNotFoundError
575         }
576         return nil
577 }
578
579 func (rh *Resthook) getMetaData(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
580         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
581         a1.Logger.Debug("instanceMetadata key : %+v", instanceMetadataKey)
582         var keys [1]string
583         keys[0] = instanceMetadataKey
584         instanceMetadataMap, err := rh.db.Get(a1MediatorNs, keys[:])
585         if err != nil {
586                 a1.Logger.Error("policy instance error : %v", err)
587         }
588         a1.Logger.Debug("instanceMetadata map : %+v", instanceMetadataMap)
589         if instanceMetadataMap[instanceMetadataKey] == nil {
590                 a1.Logger.Error("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
591                 return map[string]interface{}{}, policyInstanceNotFoundError
592         }
593         return instanceMetadataMap, nil
594 }
595
596 func (rh *Resthook) getPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) {
597         instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
598         var keys [1]string
599         keys[0] = instancehandlerKey
600         resp, err := rh.db.Get(a1MediatorNs, keys[:])
601         if err != nil {
602                 a1.Logger.Error("error1 :%+v", err)
603                 return false, err
604         }
605         for _, key := range resp {
606                 if key == "OK" {
607                         return true, nil
608                 }
609         }
610         return false, nil
611 }
612
613 func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (*a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody, error) {
614         err := rh.instanceValidity(policyTypeId, policyInstanceID)
615         policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{}
616         policyInstanceStatus.EnforceStatus = "NOT_ENFORCED"
617         policyInstanceStatus.EnforceReason = "OTHER_REASON"
618         if err != nil && (err == policyInstanceNotFoundError || err == policyTypeNotFoundError) {
619                 return &policyInstanceStatus, err
620         }
621         metadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
622         a1.Logger.Debug(" metadata %v", metadata)
623         if err != nil {
624                 a1.Logger.Error("policy instance error : %v", err)
625                 return &policyInstanceStatus, err
626         }
627         jsonbody, err := json.Marshal(metadata)
628         if err != nil {
629                 a1.Logger.Error("marshal error : %v", err)
630                 return &policyInstanceStatus, err
631         }
632
633         if err := json.Unmarshal(jsonbody, &policyInstanceStatus); err != nil {
634                 a1.Logger.Error("unmarshal error : %v", err)
635                 //this error maps to 503 error but can be mapped to 500: internal error
636                 return &policyInstanceStatus, err
637         }
638         enforced, err := rh.getPolicyInstanceStatus(policyTypeId, policyInstanceID)
639         if err != nil || (err == nil && !enforced) {
640                 a1.Logger.Error("marshal error : %v", err)
641                 return &policyInstanceStatus, err
642         }
643         policyInstanceStatus.EnforceStatus = "ENFORCED"
644         policyInstanceStatus.EnforceReason = ""
645         return &policyInstanceStatus, nil
646 }
647
648 func (rh *Resthook) storeDeletedPolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, creation_timestamp string) error {
649         deleted_timestamp := time.Now()
650
651         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
652
653         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
654
655         var metadatajson interface{}
656         metadatajson = map[string]string{"created_at": creation_timestamp, "has_been_deleted": "True", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05")}
657         a1.Logger.Debug("metadatajson to create : %+v", metadatajson)
658         deletedmetadata, err := json.Marshal(metadatajson)
659
660         a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(deletedmetadata))
661
662         err = rh.db.Set(a1MediatorNs, instanceMetadataKey, string(deletedmetadata))
663         a1.Logger.Debug("deletemetadatacreated")
664         if err != nil {
665                 a1.Logger.Error("error :%+v", err)
666                 return err
667         }
668
669         a1.Logger.Error("Policy Instance Meta Data deleted at :%+v", creation_timestamp)
670
671         return nil
672 }
673
674 func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
675         var keys [1]string
676         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
677         keys[0] = instancekey
678         err := rh.db.Remove(a1MediatorNs, keys[:])
679         if err != nil {
680                 a1.Logger.Error("error in deleting policy instance err: %v", err)
681                 return err
682         }
683         return nil
684 }
685
686 func (rh *Resthook) deleteNotificationDestination(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
687         var keys [1]string
688         notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
689         keys[0] = notificationDestinationkey
690         err := rh.db.Remove(a1MediatorNs, keys[:])
691         if err != nil {
692                 a1.Logger.Error("error in deleting notificationDestination err: %v", err)
693                 return err
694         }
695
696         return nil
697 }
698
699 func (rh *Resthook) deleteMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
700         var keys [1]string
701         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
702
703         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
704         keys[0] = instanceMetadataKey
705         err := rh.db.Remove(a1MediatorNs, keys[:])
706         if err != nil {
707                 a1.Logger.Error("error in deleting policy metadata err: %v", err)
708                 return err
709         }
710         return nil
711 }
712
713 func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
714         err := rh.instanceValidity(policyTypeId, policyInstanceID)
715         if err != nil {
716                 a1.Logger.Error("policy instance error : %v", err)
717                 if err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
718                         return err
719                 }
720         }
721
722         createdmetadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
723         if err != nil {
724                 a1.Logger.Error("error : %v", err)
725                 return err
726         }
727         a1.Logger.Debug(" created metadata %v", createdmetadata)
728         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
729         creation_metadata := createdmetadata[instanceMetadataKey]
730         var metadata map[string]interface{}
731         creation_metadata_string := creation_metadata.(string)
732         creation_metadata_string = strings.TrimRight(creation_metadata_string, "]")
733         creation_metadata_string = strings.TrimLeft(creation_metadata_string, "[")
734         if err = json.Unmarshal([]byte(creation_metadata_string), &metadata); err != nil {
735                 a1.Logger.Error("unmarshal error : %v", err)
736                 return err
737         }
738
739         a1.Logger.Debug(" created metadata created_at %v", metadata["created_at"])
740         creation_timestamp := metadata["created_at"]
741
742         rh.deleteMetadata(policyTypeId, policyInstanceID)
743
744         rh.deleteInstancedata(policyTypeId, policyInstanceID)
745
746         rh.deleteNotificationDestination(policyTypeId, policyInstanceID)
747
748         rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string))
749
750         message := rmr.Message{}
751         rmrMessage, err1 := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE")
752         if err1 != nil {
753                 a1.Logger.Error("error : %v", err1)
754                 return err1
755         }
756         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
757         if isSent {
758                 a1.Logger.Debug("rmrSendToXapp : message sent")
759         } else {
760                 //TODO:if message not sent need to return error or just log it or retry sending
761                 a1.Logger.Error("rmrSendToXapp : message not sent")
762         }
763
764         return nil
765 }
766
767 func (rh *Resthook) DataDelivery(httpBody interface{}) error {
768         a1.Logger.Debug("httpbody : %+v", httpBody)
769         mymap := httpBody.(map[string]interface{})
770         message := rmr.Message{}
771         rmrMessage, err := message.A1EIMessage(mymap["job"].(string), mymap["payload"].(string))
772         if err != nil {
773                 a1.Logger.Error("error : %v", err)
774                 return err
775         }
776         a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage)
777         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery, rmr.DefaultSubId)
778         if isSent {
779                 a1.Logger.Debug("rmrSendToXapp : message sent")
780         } else {
781                 a1.Logger.Error("rmrSendToXapp : message not sent")
782         }
783         return nil
784 }