Policy status notification handling - initial rollup
[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 {
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
159         }
160
161         if err != nil {
162                 a1.Logger.Error("error in retrieving policy type. err: %v", err)
163                 return nil
164         }
165
166         if valmap[key] == nil {
167                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
168                 return policytypeschema
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
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
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] = typekey
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 = rh.GetPolicyType(policyTypeId)
383         schemaStr, err := json.Marshal(policyTypeSchema.CreateSchema)
384         if err != nil {
385                 a1.Logger.Error("Json Marshal error : %+v", err)
386                 return err
387         }
388         a1.Logger.Debug("schema to validate %+v", string(schemaStr))
389         a1.Logger.Debug("httpbody to validate %+v", httpBody)
390         schemaString := fmt.Sprint(string(schemaStr))
391         httpBodyMarshal, err := json.Marshal(httpBody)
392         httpBodyString := string((httpBodyMarshal))
393         a1.Logger.Debug("schema to validate sprint  %+v", (schemaString))
394         a1.Logger.Debug("httpbody to validate sprint %+v", httpBodyString)
395         isvalid := validate(httpBodyString, schemaString)
396         if isvalid {
397                 var operation string
398                 operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody, notificationDestination)
399                 if err != nil {
400                         a1.Logger.Error("error :%+v", err)
401                         return err
402                 }
403                 a1.Logger.Debug("policy instance :%+v", operation)
404                 iscreated, errmetadata := rh.storePolicyInstanceMetadata(policyTypeId, policyInstanceID)
405                 if errmetadata != nil {
406                         a1.Logger.Error("error :%+v", errmetadata)
407                         return errmetadata
408                 }
409                 if iscreated {
410                         a1.Logger.Debug("policy instance metadata created")
411                 }
412
413                 message := rmr.Message{}
414                 rmrMessage, err := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation)
415                 if err != nil {
416                         a1.Logger.Error("error : %v", err)
417                         return err
418                 }
419                 isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
420                 if isSent {
421                         a1.Logger.Debug("rmrSendToXapp : message sent")
422                 } else {
423                         a1.Logger.Debug("rmrSendToXapp : message not sent")
424                 }
425
426         } else {
427                 a1.Logger.Error("%+v", invalidJsonSchema)
428                 return invalidJsonSchema
429         }
430
431         return nil
432 }
433
434 func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
435         a1.Logger.Debug("GetPolicyInstance1")
436
437         var keys [1]string
438
439         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
440         keys[0] = typekey
441
442         a1.Logger.Debug("key1 : %+v", typekey)
443
444         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
445         if len(valmap) == 0 {
446                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
447                 return map[string]interface{}{}, policyTypeNotFoundError
448         }
449
450         if err != nil {
451                 a1.Logger.Error("error in retrieving policy type. err: %v", err)
452                 return map[string]interface{}{}, err
453         }
454
455         if valmap[typekey] == nil {
456                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
457                 return map[string]interface{}{}, policyTypeNotFoundError
458         }
459
460         a1.Logger.Debug("keysmap : %+v", valmap[typekey])
461
462         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
463         a1.Logger.Debug("key2 : %+v", instancekey)
464         keys[0] = instancekey
465         instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
466         if err != nil {
467                 a1.Logger.Error("policy instance error : %v", err)
468         }
469         a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
470
471         if instanceMap[instancekey] == nil {
472                 a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
473                 return map[string]interface{}{}, policyInstanceNotFoundError
474         }
475
476         var valStr map[string]interface{}
477         err = json.Unmarshal([]byte(instanceMap[instancekey].(string)), &valStr)
478         if err != nil {
479                 fmt.Println("error:", err)
480         }
481         fmt.Println(valStr)
482         return valStr, nil
483 }
484
485 func (rh *Resthook) GetAllPolicyInstance(policyTypeId models.PolicyTypeID) ([]models.PolicyInstanceID, error) {
486         a1.Logger.Debug("GetAllPolicyInstance")
487         var policyTypeInstances = []models.PolicyInstanceID{}
488
489         keys, err := rh.db.GetAll("A1m_ns")
490
491         if err != nil {
492                 a1.Logger.Error("error in retrieving policy. err: %v", err)
493                 return policyTypeInstances, err
494         }
495         a1.Logger.Debug("keys : %+v", keys)
496         typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "."
497
498         for _, key := range keys {
499                 if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) {
500                         pti := strings.Split(strings.Trim(key, " "), typekey)[1]
501                         a1.Logger.Debug("pti %+v", pti)
502                         policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti))
503                 }
504         }
505
506         if len(policyTypeInstances) == 0 {
507                 a1.Logger.Debug("policy instance Not Present  ")
508         }
509
510         a1.Logger.Debug("return : %+v", policyTypeInstances)
511         return policyTypeInstances, nil
512 }
513
514 func (rh *Resthook) DeletePolicyType(policyTypeId models.PolicyTypeID) error {
515         a1.Logger.Debug("DeletePolicyType")
516
517         policyinstances, err := rh.GetAllPolicyInstance(policyTypeId)
518         if err != nil {
519                 a1.Logger.Error("error in retrieving policy. err: %v", err)
520                 return err
521         }
522
523         var keys [1]string
524         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
525         keys[0] = key
526         if len(policyinstances) == 0 {
527                 err := rh.db.Remove(a1MediatorNs, keys[:])
528                 if err != nil {
529                         a1.Logger.Error("error in deleting policy type err: %v", err)
530                         return err
531                 }
532         } else {
533                 a1.Logger.Error("tried to delete a type that isn't empty")
534                 return policyTypeCanNotBeDeletedError
535         }
536         return nil
537 }
538
539 func (rh *Resthook) typeValidity(policyTypeId models.PolicyTypeID) error {
540         var keys [1]string
541
542         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
543         keys[0] = typekey
544
545         a1.Logger.Debug("key1 : %+v", typekey)
546         valmap, err := rh.db.Get(a1MediatorNs, keys[:])
547         if err != nil {
548                 a1.Logger.Error("error in retrieving policytype err: %v", err)
549                 return err
550         }
551         if len(valmap) == 0 {
552                 a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
553                 return policyTypeNotFoundError
554         }
555         return nil
556 }
557
558 func (rh *Resthook) instanceValidity(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
559         err := rh.typeValidity(policyTypeId)
560         if err != nil {
561                 return err
562         }
563         policyTypeInstances, err := rh.GetPolicyInstance(policyTypeId, policyInstanceID)
564         if err != nil {
565                 a1.Logger.Error("policy instance error : %v", err)
566                 return err
567         }
568         if policyTypeInstances == nil {
569                 a1.Logger.Debug("policy instance Not Present  ")
570                 return policyInstanceNotFoundError
571         }
572         return nil
573 }
574
575 func (rh *Resthook) getMetaData(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
576         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
577         a1.Logger.Debug("instanceMetadata key : %+v", instanceMetadataKey)
578         var keys [1]string
579         keys[0] = instanceMetadataKey
580         instanceMetadataMap, err := rh.db.Get(a1MediatorNs, keys[:])
581         if err != nil {
582                 a1.Logger.Error("policy instance error : %v", err)
583         }
584         a1.Logger.Debug("instanceMetadata map : %+v", instanceMetadataMap)
585         if instanceMetadataMap[instanceMetadataKey] == nil {
586                 a1.Logger.Error("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
587                 return map[string]interface{}{}, policyInstanceNotFoundError
588         }
589         return instanceMetadataMap, nil
590 }
591
592 func (rh *Resthook) getPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) {
593         instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
594         var keys [1]string
595         keys[0] = instancehandlerKey
596         resp, err := rh.db.Get(a1MediatorNs, keys[:])
597         if err != nil {
598                 a1.Logger.Error("error1 :%+v", err)
599                 return false, err
600         }
601         for _, key := range resp {
602                 if key == "OK" {
603                         return true, nil
604                 }
605         }
606         return false, nil
607 }
608
609 func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (*a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody, error) {
610         err := rh.instanceValidity(policyTypeId, policyInstanceID)
611         policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{}
612         policyInstanceStatus.EnforceStatus = "NOT_ENFORCED"
613         policyInstanceStatus.EnforceReason = "OTHER_REASON"
614         if err != nil && (err == policyInstanceNotFoundError || err == policyTypeNotFoundError) {
615                 return &policyInstanceStatus, err
616         }
617         metadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
618         a1.Logger.Debug(" metadata %v", metadata)
619         if err != nil {
620                 a1.Logger.Error("policy instance error : %v", err)
621                 return &policyInstanceStatus, err
622         }
623         jsonbody, err := json.Marshal(metadata)
624         if err != nil {
625                 a1.Logger.Error("marshal error : %v", err)
626                 return &policyInstanceStatus, err
627         }
628
629         if err := json.Unmarshal(jsonbody, &policyInstanceStatus); err != nil {
630                 a1.Logger.Error("unmarshal error : %v", err)
631                 //this error maps to 503 error but can be mapped to 500: internal error
632                 return &policyInstanceStatus, err
633         }
634         enforced, err := rh.getPolicyInstanceStatus(policyTypeId, policyInstanceID)
635         if err != nil || (err == nil && !enforced) {
636                 a1.Logger.Error("marshal error : %v", err)
637                 return &policyInstanceStatus, err
638         }
639         policyInstanceStatus.EnforceStatus = "ENFORCED"
640         policyInstanceStatus.EnforceReason = ""
641         return &policyInstanceStatus, nil
642 }
643
644 func (rh *Resthook) storeDeletedPolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, creation_timestamp string) error {
645         deleted_timestamp := time.Now()
646
647         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
648
649         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
650
651         var metadatajson interface{}
652         metadatajson = map[string]string{"created_at": creation_timestamp, "has_been_deleted": "True", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05")}
653         a1.Logger.Debug("metadatajson to create : %+v", metadatajson)
654         deletedmetadata, err := json.Marshal(metadatajson)
655
656         a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(deletedmetadata))
657
658         err = rh.db.Set(a1MediatorNs, instanceMetadataKey, string(deletedmetadata))
659         a1.Logger.Debug("deletemetadatacreated")
660         if err != nil {
661                 a1.Logger.Error("error :%+v", err)
662                 return err
663         }
664
665         a1.Logger.Error("Policy Instance Meta Data deleted at :%+v", creation_timestamp)
666
667         return nil
668 }
669
670 func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
671         var keys [1]string
672         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
673         keys[0] = instancekey
674         err := rh.db.Remove(a1MediatorNs, keys[:])
675         if err != nil {
676                 a1.Logger.Error("error in deleting policy instance err: %v", err)
677                 return err
678         }
679         return nil
680 }
681
682 func (rh *Resthook) deleteNotificationDestination(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
683         var keys [1]string
684         notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
685         keys[0] = notificationDestinationkey
686         err := rh.db.Remove(a1MediatorNs, keys[:])
687         if err != nil {
688                 a1.Logger.Error("error in deleting notificationDestination err: %v", err)
689                 return err
690         }
691
692         return nil
693 }
694
695 func (rh *Resthook) deleteMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
696         var keys [1]string
697         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
698
699         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
700         keys[0] = instanceMetadataKey
701         err := rh.db.Remove(a1MediatorNs, keys[:])
702         if err != nil {
703                 a1.Logger.Error("error in deleting policy metadata err: %v", err)
704                 return err
705         }
706         return nil
707 }
708
709 func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
710         err := rh.instanceValidity(policyTypeId, policyInstanceID)
711         if err != nil {
712                 a1.Logger.Error("policy instance error : %v", err)
713                 if err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
714                         return err
715                 }
716         }
717
718         createdmetadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
719         if err != nil {
720                 a1.Logger.Error("error : %v", err)
721                 return err
722         }
723         a1.Logger.Debug(" created metadata %v", createdmetadata)
724         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
725         creation_metadata := createdmetadata[instanceMetadataKey]
726         var metadata map[string]interface{}
727         creation_metadata_string := creation_metadata.(string)
728         creation_metadata_string = strings.TrimRight(creation_metadata_string, "]")
729         creation_metadata_string = strings.TrimLeft(creation_metadata_string, "[")
730         if err = json.Unmarshal([]byte(creation_metadata_string), &metadata); err != nil {
731                 a1.Logger.Error("unmarshal error : %v", err)
732                 return err
733         }
734
735         a1.Logger.Debug(" created metadata created_at %v", metadata["created_at"])
736         creation_timestamp := metadata["created_at"]
737
738         rh.deleteMetadata(policyTypeId, policyInstanceID)
739
740         rh.deleteInstancedata(policyTypeId, policyInstanceID)
741
742         rh.deleteNotificationDestination(policyTypeId, policyInstanceID)
743
744         rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string))
745
746         message := rmr.Message{}
747         rmrMessage, err1 := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE")
748         if err1 != nil {
749                 a1.Logger.Error("error : %v", err1)
750                 return err1
751         }
752         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
753         if isSent {
754                 a1.Logger.Debug("rmrSendToXapp : message sent")
755         } else {
756                 //TODO:if message not sent need to return error or just log it or retry sending
757                 a1.Logger.Error("rmrSendToXapp : message not sent")
758         }
759
760         return nil
761 }
762
763 func (rh *Resthook) DataDelivery(httpBody interface{}) error {
764         a1.Logger.Debug("httpbody : %+v", httpBody)
765         mymap := httpBody.(map[string]interface{})
766         message := rmr.Message{}
767         rmrMessage, err := message.A1EIMessage(mymap["job"].(string), mymap["payload"].(string))
768         if err != nil {
769                 a1.Logger.Error("error : %v", err)
770                 return err
771         }
772         a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage)
773         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery, rmr.DefaultSubId)
774         if isSent {
775                 a1.Logger.Debug("rmrSendToXapp : message sent")
776         } else {
777                 a1.Logger.Error("rmrSendToXapp : message not sent")
778         }
779         return nil
780 }