cf7a2d18f3b0ca1bb0cafa563078d8ca10b8be9b
[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) (bool, error) {
576         instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
577         var keys [1]string
578         keys[0] = instancehandlerKey
579         resp, err := rh.db.Get(a1MediatorNs, keys[:])
580         if err != nil {
581                 a1.Logger.Error("error1 :%+v", err)
582                 return false, err
583         }
584         for _, key := range resp {
585                 if key == "OK" {
586                         return true, nil
587                 }
588         }
589         return false, nil
590 }
591
592 func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (*a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody, error) {
593         err := rh.instanceValidity(policyTypeId, policyInstanceID)
594         policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{}
595         policyInstanceStatus.InstanceStatus = "NOT IN EFFECT"
596         if err != nil && err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
597                 return &policyInstanceStatus, err
598         }
599         metadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
600         a1.Logger.Debug(" metadata %v", metadata)
601         if err != nil {
602                 a1.Logger.Error("policy instance error : %v", err)
603                 return &policyInstanceStatus, err
604         }
605         jsonbody, err := json.Marshal(metadata)
606         if err != nil {
607                 a1.Logger.Error("marshal error : %v", err)
608                 return &policyInstanceStatus, err
609         }
610
611         if err := json.Unmarshal(jsonbody, &policyInstanceStatus); err != nil {
612                 a1.Logger.Error("unmarshal error : %v", err)
613                 //this error maps to 503 error but can be mapped to 500: internal error
614                 return &policyInstanceStatus, err
615         }
616         resp, err := rh.getPolicyInstanceStatus(policyTypeId, policyInstanceID)
617         if err != nil || (err == nil && resp == false) {
618                 a1.Logger.Error("marshal error : %v", err)
619                 return &policyInstanceStatus, err
620         } else if policyInstanceStatus.HasBeenDeleted == true {
621                 policyInstanceStatus.InstanceStatus = "IN EFFECT"
622         }
623         return &policyInstanceStatus, nil
624 }
625
626 func (rh *Resthook) storeDeletedPolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, creation_timestamp string) error {
627         deleted_timestamp := time.Now()
628
629         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
630
631         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
632
633         var metadatajson interface{}
634         metadatajson = map[string]string{"created_at": creation_timestamp, "has_been_deleted": "True", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05")}
635         a1.Logger.Debug("metadatajson to create : %+v", metadatajson)
636         deletedmetadata, err := json.Marshal(metadatajson)
637
638         a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(deletedmetadata))
639
640         err = rh.db.Set(a1MediatorNs, instanceMetadataKey, string(deletedmetadata))
641         a1.Logger.Debug("deletemetadatacreated")
642         if err != nil {
643                 a1.Logger.Error("error :%+v", err)
644                 return err
645         }
646
647         a1.Logger.Error("Policy Instance Meta Data deleted at :%+v", creation_timestamp)
648
649         return nil
650 }
651
652 func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
653         var keys [1]string
654         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
655         keys[0] = instancekey
656         err := rh.db.Remove(a1MediatorNs, keys[:])
657         if err != nil {
658                 a1.Logger.Error("error in deleting policy type err: %v", err)
659                 return err
660         }
661         return nil
662 }
663
664 func (rh *Resthook) deleteMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
665         var keys [1]string
666         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
667
668         a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
669         keys[0] = instanceMetadataKey
670         err := rh.db.Remove(a1MediatorNs, keys[:])
671         if err != nil {
672                 a1.Logger.Error("error in deleting policy metadata err: %v", err)
673                 return err
674         }
675         return nil
676 }
677
678 func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
679         err := rh.instanceValidity(policyTypeId, policyInstanceID)
680         if err != nil {
681                 a1.Logger.Error("policy instance error : %v", err)
682                 if err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
683                         return err
684                 }
685         }
686
687         createdmetadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
688         if err != nil {
689                 a1.Logger.Error("error : %v", err)
690                 return err
691         }
692         a1.Logger.Debug(" created metadata %v", createdmetadata)
693         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
694         creation_metadata := createdmetadata[instanceMetadataKey]
695         var metadata map[string]interface{}
696         creation_metadata_string := creation_metadata.(string)
697         creation_metadata_string = strings.TrimRight(creation_metadata_string, "]")
698         creation_metadata_string = strings.TrimLeft(creation_metadata_string, "[")
699         if err = json.Unmarshal([]byte(creation_metadata_string), &metadata); err != nil {
700                 a1.Logger.Error("unmarshal error : %v", err)
701                 return err
702         }
703
704         a1.Logger.Debug(" created metadata created_at %v", metadata["created_at"])
705         creation_timestamp := metadata["created_at"]
706
707         rh.deleteMetadata(policyTypeId, policyInstanceID)
708
709         rh.deleteInstancedata(policyTypeId, policyInstanceID)
710
711         rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string))
712
713         message := rmr.Message{}
714         rmrMessage, err1 := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE")
715         if err1 != nil {
716                 a1.Logger.Error("error : %v", err1)
717                 return err1
718         }
719         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest)
720         if isSent {
721                 a1.Logger.Debug("rmrSendToXapp : message sent")
722         } else {
723                 //TODO:if message not sent need to return error or just log it or retry sending
724                 a1.Logger.Error("rmrSendToXapp : message not sent")
725         }
726
727         return nil
728 }
729
730 func (rh *Resthook) DataDelivery(httpBody interface{}) error {
731         a1.Logger.Debug("httpbody : %+v", httpBody)
732         mymap := httpBody.(map[string]interface{})
733         message := rmr.Message{}
734         rmrMessage, err := message.A1EIMessage(mymap["job"].(string), mymap["payload"].(string))
735         if err != nil {
736                 a1.Logger.Error("error : %v", err)
737                 return err
738         }
739         a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage)
740         isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery)
741         if isSent {
742                 a1.Logger.Debug("rmrSendToXapp : message sent")
743         } else {
744                 a1.Logger.Error("rmrSendToXapp : message not sent")
745         }
746         return nil
747 }