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