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