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