Replacing a1-python with a1-go implementation
[ric-plt/a1.git] / pkg / resthooks / resthooks.go
diff --git a/pkg/resthooks/resthooks.go b/pkg/resthooks/resthooks.go
new file mode 100644 (file)
index 0000000..dcffe2a
--- /dev/null
@@ -0,0 +1,721 @@
+/*
+==================================================================================
+  Copyright (c) 2021 Samsung
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+   platform project (RICP).
+==================================================================================
+*/
+package resthooks
+
+import (
+       "encoding/json"
+       "errors"
+       "fmt"
+       "strconv"
+       "strings"
+       "time"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1"
+       "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models"
+       "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/policy"
+       "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/restapi/operations/a1_mediator"
+       "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/rmr"
+       "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+       "github.com/santhosh-tekuri/jsonschema/v5"
+       "gopkg.in/yaml.v2"
+)
+
+const (
+       a1PolicyPrefix           = "a1.policy_type."
+       a1MediatorNs             = "A1m_ns"
+       a1InstancePrefix         = "a1.policy_instance."
+       a1InstanceMetadataPrefix = "a1.policy_inst_metadata."
+       a1HandlerPrefix          = "a1.policy_handler."
+       a1PolicyRequest          = 20010
+       a1EIDataDelivery         = 20017
+)
+
+var typeAlreadyError = errors.New("Policy Type already exists")
+var InstanceAlreadyError = errors.New("Policy Instance already exists")
+var typeMismatchError = errors.New("Policytype Mismatch")
+var invalidJsonSchema = errors.New("Invalid Json ")
+var policyInstanceNotFoundError = errors.New("Policy Instance Not Found")
+var policyTypeNotFoundError = errors.New("Policy Type Not Found")
+var policyTypeCanNotBeDeletedError = errors.New("tried to delete a type that isn't empty")
+var policyInstanceCanNotBeDeletedError = errors.New("tried to delete a Instance that isn't empty")
+
+func (rh *Resthook) CanPolicyInstanceBeDeleted(err error) bool {
+       return err == policyInstanceCanNotBeDeletedError
+}
+
+func (rh *Resthook) CanPolicyTypeBeDeleted(err error) bool {
+       return err == policyTypeCanNotBeDeletedError
+}
+
+func (rh *Resthook) IsPolicyTypePresent(err error) bool {
+       return err == policyTypeNotFoundError
+}
+
+func (rh *Resthook) IsPolicyInstanceNotFound(err error) bool {
+       return err == policyInstanceNotFoundError
+}
+
+func (rh *Resthook) IsTypeAlready(err error) bool {
+       return err == typeAlreadyError
+}
+func (rh *Resthook) IsInstanceAlready(err error) bool {
+       return err == InstanceAlreadyError
+}
+func (rh *Resthook) IsTypeMismatch(err error) bool {
+       return err == typeMismatchError
+}
+
+func (rh *Resthook) IsValidJson(err error) bool {
+       return err == invalidJsonSchema
+}
+func NewResthook() *Resthook {
+       sdl := sdlgo.NewSyncStorage()
+       policyManager := policy.NewPolicyManager(sdl)
+       return createResthook(sdl, rmr.NewRMRSender(policyManager))
+}
+
+func createResthook(sdlInst iSdl, rmrSenderInst rmr.IRmrSender) *Resthook {
+       rh := &Resthook{
+               db:             sdlInst,
+               iRmrSenderInst: rmrSenderInst,
+       }
+
+       return rh
+}
+
+func (rh *Resthook) GetA1Health() bool {
+       data, _ := rh.db.GetAll(a1MediatorNs)
+       if data != nil {
+               a1.Logger.Debug("Database connected and A1 is healthy")
+               return true
+       }
+       return false
+}
+
+func (rh *Resthook) GetAllPolicyType() []models.PolicyTypeID {
+
+       var policyTypeIDs []models.PolicyTypeID
+
+       keys, err := rh.db.GetAll("A1m_ns")
+
+       if err != nil {
+               a1.Logger.Error("error in retrieving policy. err: %v", err)
+               return policyTypeIDs
+       }
+       a1.Logger.Debug("keys : %+v", keys)
+
+       for _, key := range keys {
+               if strings.HasPrefix(strings.TrimLeft(key, " "), a1PolicyPrefix) {
+                       pti := strings.Split(strings.Trim(key, " "), a1PolicyPrefix)[1]
+                       ptii, _ := strconv.ParseInt(pti, 10, 64)
+                       policyTypeIDs = append(policyTypeIDs, models.PolicyTypeID(ptii))
+               }
+       }
+
+       a1.Logger.Debug("return : %+v", policyTypeIDs)
+       return policyTypeIDs
+}
+
+func (rh *Resthook) GetPolicyType(policyTypeId models.PolicyTypeID) *models.PolicyTypeSchema {
+       a1.Logger.Debug("GetPolicyType1")
+
+       var policytypeschema *models.PolicyTypeSchema
+       var keys [1]string
+
+       key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       keys[0] = key
+
+       a1.Logger.Debug("key : %+v", key)
+
+       valmap, err := rh.db.Get(a1MediatorNs, keys[:])
+
+       a1.Logger.Debug("policytype map : %+v", valmap)
+
+       if len(valmap) == 0 {
+               a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
+               return policytypeschema
+       }
+
+       if err != nil {
+               a1.Logger.Error("error in retrieving policy type. err: %v", err)
+               return nil
+       }
+
+       if valmap[key] == nil {
+               a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
+               return policytypeschema
+       }
+
+       a1.Logger.Debug("keysmap : %+v", valmap[key])
+
+       var item models.PolicyTypeSchema
+       valStr := fmt.Sprint(valmap[key])
+
+       a1.Logger.Debug("Policy type for %+v :  %+v", key, valStr)
+       valkey := "`" + valStr + "`"
+       valToUnmarshall, err := strconv.Unquote(valkey)
+       if err != nil {
+               a1.Logger.Error("unquote error : %+v", err)
+               return nil
+       }
+
+       a1.Logger.Debug("Policy type for %+v :  %+v", key, string(valToUnmarshall))
+
+       errunm := json.Unmarshal([]byte(valToUnmarshall), &item)
+
+       a1.Logger.Debug(" Unmarshalled json : %+v", (errunm))
+       a1.Logger.Debug("Policy type Name :  %v", (item.Name))
+
+       return &item
+}
+
+func (rh *Resthook) CreatePolicyType(policyTypeId models.PolicyTypeID, httprequest models.PolicyTypeSchema) error {
+       a1.Logger.Debug("CreatePolicyType function")
+       if policyTypeId != models.PolicyTypeID(*httprequest.PolicyTypeID) {
+               //error message
+               a1.Logger.Debug("Policytype Mismatch")
+               return typeMismatchError
+       }
+       key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       a1.Logger.Debug("key %+v ", key)
+       if data, err := httprequest.MarshalBinary(); err == nil {
+               a1.Logger.Debug("Marshaled String : %+v", string(data))
+               success, err1 := rh.db.SetIfNotExists(a1MediatorNs, key, string(data))
+               a1.Logger.Info("success:%+v", success)
+               if err1 != nil {
+                       a1.Logger.Error("error :%+v", err1)
+                       return err1
+               }
+               if !success {
+                       a1.Logger.Debug("Policy type %+v already exist", policyTypeId)
+                       return typeAlreadyError
+               }
+       }
+       return nil
+}
+
+func toStringKeys(val interface{}) (interface{}, error) {
+       var err error
+       switch val := val.(type) {
+       case map[interface{}]interface{}:
+               m := make(map[string]interface{})
+               for k, v := range val {
+                       k, ok := k.(string)
+                       if !ok {
+                               return nil, errors.New("found non-string key")
+                       }
+                       m[k], err = toStringKeys(v)
+                       if err != nil {
+                               return nil, err
+                       }
+               }
+               return m, nil
+       case []interface{}:
+               var l = make([]interface{}, len(val))
+               for i, v := range val {
+                       l[i], err = toStringKeys(v)
+                       if err != nil {
+                               return nil, err
+                       }
+               }
+               return l, nil
+       default:
+               return val, nil
+       }
+}
+
+func validate(httpBodyString string, schemaString string) bool {
+       var m interface{}
+       err := yaml.Unmarshal([]byte(httpBodyString), &m)
+       if err != nil {
+               a1.Logger.Error("Unmarshal error : %+v", err)
+       }
+       m, err = toStringKeys(m)
+       if err != nil {
+               a1.Logger.Error("Conversion to string error : %+v", err)
+               return false
+       }
+       compiler := jsonschema.NewCompiler()
+       if err := compiler.AddResource("schema.json", strings.NewReader(schemaString)); err != nil {
+               a1.Logger.Error("string reader error : %+v", err)
+               return false
+       }
+       schema, err := compiler.Compile("schema.json")
+       if err != nil {
+               a1.Logger.Error("schema json compile error : %+v", err)
+               return false
+       }
+       if err := schema.Validate(m); err != nil {
+               a1.Logger.Error("schema validation error : %+v", err)
+               return false
+       }
+       a1.Logger.Debug("validation successfull")
+       return true
+}
+
+func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) (string, error) {
+       var keys [1]string
+       operation := "CREATE"
+       typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       keys[0] = typekey
+
+       a1.Logger.Debug("key1 : %+v", typekey)
+
+       valmap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("policy type error : %+v", err)
+       }
+       a1.Logger.Debug("policytype map : %+v", valmap)
+       if valmap[typekey] == nil {
+               a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
+               return operation, policyTypeNotFoundError
+       }
+       // TODO : rmr creation_timestamp := time.Now() // will be needed for rmr to notify the creation of instance
+
+       instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       keys[0] = typekey
+       instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("policy type error : %v", err)
+       }
+       a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
+
+       if instanceMap[instancekey] != nil {
+               operation = "UPDATE"
+               a1.Logger.Debug("UPDATE")
+               data, _ := json.Marshal(httpBody)
+               a1.Logger.Debug("Marshaled String : %+v", string(data))
+               a1.Logger.Debug("key   : %+v", instancekey)
+               success, err1 := rh.db.SetIf(a1MediatorNs, instancekey, instanceMap[instancekey], string(data))
+               if err1 != nil {
+                       a1.Logger.Error("error2 :%+v", err1)
+                       return operation, err1
+               }
+               if !success {
+                       a1.Logger.Debug("Policy instance %+v already exist", policyInstanceID)
+                       return operation, InstanceAlreadyError
+               }
+       } else {
+               data, _ := json.Marshal(httpBody)
+               a1.Logger.Debug("Marshaled String : %+v", string(data))
+               a1.Logger.Debug("key   : %+v", instancekey)
+
+               var instance_map []interface{}
+               instance_map = append(instance_map, instancekey, string(data))
+               a1.Logger.Debug("policyinstancetype map : %+v", instance_map[1])
+               a1.Logger.Debug("policyinstancetype to create : %+v", instance_map)
+
+               err1 := rh.db.Set(a1MediatorNs, instancekey, string(data))
+               if err1 != nil {
+                       a1.Logger.Error("error1 :%+v", err1)
+                       return operation, err1
+               }
+       }
+       a1.Logger.Debug("Policy Instance created ")
+       return operation, nil
+}
+
+func (rh *Resthook) storePolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) {
+
+       creation_timestamp := time.Now()
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+
+       a1.Logger.Debug("key : %+v", instanceMetadataKey)
+
+       var metadatajson []interface{}
+       metadatajson = append(metadatajson, map[string]string{"created_at": creation_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "False"})
+       metadata, _ := json.Marshal(metadatajson)
+
+       a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(metadata))
+
+       err := rh.db.Set(a1MediatorNs, instanceMetadataKey, string(metadata))
+
+       if err != nil {
+               a1.Logger.Error("error :%+v", err)
+               return false, err
+       }
+
+       a1.Logger.Debug("Policy Instance Meta Data created at :%+v", creation_timestamp)
+
+       return true, nil
+}
+
+func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) error {
+       a1.Logger.Debug("CreatePolicyInstance function")
+       //  validate the PUT against the schema
+       var policyTypeSchema *models.PolicyTypeSchema
+       policyTypeSchema = rh.GetPolicyType(policyTypeId)
+       schemaStr, err := json.Marshal(policyTypeSchema.CreateSchema)
+       if err != nil {
+               a1.Logger.Error("Json Marshal error : %+v", err)
+               return err
+       }
+       a1.Logger.Debug("schema to validate %+v", string(schemaStr))
+       a1.Logger.Debug("httpbody to validate %+v", httpBody)
+       schemaString := fmt.Sprint(string(schemaStr))
+       httpBodyMarshal, err := json.Marshal(httpBody)
+       httpBodyString := string((httpBodyMarshal))
+       a1.Logger.Debug("schema to validate sprint  %+v", (schemaString))
+       a1.Logger.Debug("httpbody to validate sprint %+v", httpBodyString)
+       isvalid := validate(httpBodyString, schemaString)
+       if isvalid {
+               var operation string
+               operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody)
+               if err != nil {
+                       a1.Logger.Error("error :%+v", err)
+                       return err
+               }
+               a1.Logger.Debug("policy instance :%+v", operation)
+               iscreated, errmetadata := rh.storePolicyInstanceMetadata(policyTypeId, policyInstanceID)
+               if errmetadata != nil {
+                       a1.Logger.Error("error :%+v", errmetadata)
+                       return errmetadata
+               }
+               if iscreated {
+                       a1.Logger.Debug("policy instance metadata created")
+               }
+
+               message := rmr.Message{}
+               rmrMessage, err := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation)
+               if err != nil {
+                       a1.Logger.Error("error : %v", err)
+                       return err
+               }
+               isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest)
+               if isSent {
+                       a1.Logger.Debug("rmrSendToXapp : message sent")
+               } else {
+                       a1.Logger.Debug("rmrSendToXapp : message not sent")
+               }
+
+       } else {
+               a1.Logger.Error("%+v", invalidJsonSchema)
+               return invalidJsonSchema
+       }
+
+       return nil
+}
+
+func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (interface{}, error) {
+       a1.Logger.Debug("GetPolicyInstance1")
+
+       var keys [1]string
+
+       typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       keys[0] = typekey
+
+       a1.Logger.Debug("key1 : %+v", typekey)
+
+       valmap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if len(valmap) == 0 {
+               a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
+               return "{}", policyTypeNotFoundError
+       }
+
+       if err != nil {
+               a1.Logger.Error("error in retrieving policy type. err: %v", err)
+               return "{}", err
+       }
+
+       if valmap[typekey] == nil {
+               a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
+               return "{}", policyTypeNotFoundError
+       }
+
+       a1.Logger.Debug("keysmap : %+v", valmap[typekey])
+
+       instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       a1.Logger.Debug("key2 : %+v", instancekey)
+       keys[0] = instancekey
+       instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("policy instance error : %v", err)
+       }
+       a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
+
+       if instanceMap[instancekey] == nil {
+               a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
+               return "{}", policyInstanceNotFoundError
+       }
+
+       valStr := fmt.Sprint(instanceMap[instancekey])
+       return valStr, nil
+}
+
+func (rh *Resthook) GetAllPolicyInstance(policyTypeId models.PolicyTypeID) ([]models.PolicyInstanceID, error) {
+       a1.Logger.Debug("GetAllPolicyInstance")
+       var policyTypeInstances = []models.PolicyInstanceID{}
+
+       keys, err := rh.db.GetAll("A1m_ns")
+
+       if err != nil {
+               a1.Logger.Error("error in retrieving policy. err: %v", err)
+               return policyTypeInstances, err
+       }
+       a1.Logger.Debug("keys : %+v", keys)
+       typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "."
+
+       for _, key := range keys {
+               if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) {
+                       pti := strings.Split(strings.Trim(key, " "), typekey)[1]
+                       a1.Logger.Debug("pti %+v", pti)
+                       policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti))
+               }
+       }
+
+       if len(policyTypeInstances) == 0 {
+               a1.Logger.Debug("policy instance Not Present  ")
+       }
+
+       a1.Logger.Debug("return : %+v", policyTypeInstances)
+       return policyTypeInstances, nil
+}
+
+func (rh *Resthook) DeletePolicyType(policyTypeId models.PolicyTypeID) error {
+       a1.Logger.Debug("DeletePolicyType")
+
+       policyinstances, err := rh.GetAllPolicyInstance(policyTypeId)
+       if err != nil {
+               a1.Logger.Error("error in retrieving policy. err: %v", err)
+               return err
+       }
+
+       var keys [1]string
+       key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       keys[0] = key
+       if len(policyinstances) == 0 {
+               err := rh.db.Remove(a1MediatorNs, keys[:])
+               if err != nil {
+                       a1.Logger.Error("error in deleting policy type err: %v", err)
+                       return err
+               }
+       } else {
+               a1.Logger.Error("tried to delete a type that isn't empty")
+               return policyTypeCanNotBeDeletedError
+       }
+       return nil
+}
+
+func (rh *Resthook) typeValidity(policyTypeId models.PolicyTypeID) error {
+       var keys [1]string
+
+       typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       keys[0] = typekey
+
+       a1.Logger.Debug("key1 : %+v", typekey)
+       valmap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("error in retrieving policytype err: %v", err)
+               return err
+       }
+       if len(valmap) == 0 {
+               a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId)
+               return policyTypeNotFoundError
+       }
+       return nil
+}
+
+func (rh *Resthook) instanceValidity(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
+       err := rh.typeValidity(policyTypeId)
+       if err != nil {
+               return err
+       }
+       policyTypeInstances, err := rh.GetPolicyInstance(policyTypeId, policyInstanceID)
+       if err != nil {
+               a1.Logger.Error("policy instance error : %v", err)
+               return err
+       }
+       if len(policyTypeInstances.(string)) == 0 {
+               a1.Logger.Debug("policy instance Not Present  ")
+               return policyInstanceNotFoundError
+       }
+       return nil
+}
+
+func (rh *Resthook) getMetaData(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       a1.Logger.Debug("instanceMetadata key : %+v", instanceMetadataKey)
+       var keys [1]string
+       keys[0] = instanceMetadataKey
+       instanceMetadataMap, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("policy instance error : %v", err)
+       }
+       a1.Logger.Debug("instanceMetadata map : %+v", instanceMetadataMap)
+       if instanceMetadataMap[instanceMetadataKey] == nil {
+               a1.Logger.Error("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
+               return map[string]interface{}{}, policyInstanceNotFoundError
+       }
+       return instanceMetadataMap, nil
+}
+
+func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (*a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody, error) {
+       err := rh.instanceValidity(policyTypeId, policyInstanceID)
+       policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{}
+       if err != nil && err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
+               policyInstanceStatus.InstanceStatus = "NOT IN EFFECT"
+               return &policyInstanceStatus, err
+       }
+       metadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
+       a1.Logger.Debug(" metadata %v", metadata)
+       if err != nil {
+               a1.Logger.Error("policy instance error : %v", err)
+               policyInstanceStatus.InstanceStatus = "NOT IN EFFECT"
+               return &policyInstanceStatus, err
+       }
+       jsonbody, err := json.Marshal(metadata)
+       if err != nil {
+               a1.Logger.Error("marshal error : %v", err)
+               return &policyInstanceStatus, err
+       }
+
+       if err := json.Unmarshal(jsonbody, &policyInstanceStatus); err != nil {
+               a1.Logger.Error("unmarshal error : %v", err)
+               //this error maps to 503 error but can be mapped to 500: internal error
+               return &policyInstanceStatus, err
+       }
+       if policyInstanceStatus.HasBeenDeleted == false {
+               policyInstanceStatus.InstanceStatus = "IN EFFECT"
+       } else {
+               policyInstanceStatus.InstanceStatus = "NOT IN EFFECT"
+       }
+       return &policyInstanceStatus, nil
+}
+
+func (rh *Resthook) storeDeletedPolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, creation_timestamp string) error {
+       deleted_timestamp := time.Now()
+
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+
+       a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
+
+       var metadatajson interface{}
+       metadatajson = map[string]string{"created_at": creation_timestamp, "has_been_deleted": "True", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05")}
+       a1.Logger.Debug("metadatajson to create : %+v", metadatajson)
+       deletedmetadata, err := json.Marshal(metadatajson)
+
+       a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(deletedmetadata))
+
+       err = rh.db.Set(a1MediatorNs, instanceMetadataKey, string(deletedmetadata))
+       a1.Logger.Debug("deletemetadatacreated")
+       if err != nil {
+               a1.Logger.Error("error :%+v", err)
+               return err
+       }
+
+       a1.Logger.Error("Policy Instance Meta Data deleted at :%+v", creation_timestamp)
+
+       return nil
+}
+
+func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
+       var keys [1]string
+       instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       keys[0] = instancekey
+       err := rh.db.Remove(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("error in deleting policy type err: %v", err)
+               return err
+       }
+       return nil
+}
+
+func (rh *Resthook) deleteMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
+       var keys [1]string
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+
+       a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey)
+       keys[0] = instanceMetadataKey
+       err := rh.db.Remove(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("error in deleting policy metadata err: %v", err)
+               return err
+       }
+       return nil
+}
+
+func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
+       err := rh.instanceValidity(policyTypeId, policyInstanceID)
+       if err != nil {
+               a1.Logger.Error("policy instance error : %v", err)
+               if err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
+                       return err
+               }
+       }
+
+       createdmetadata, err := rh.getMetaData(policyTypeId, policyInstanceID)
+       if err != nil {
+               a1.Logger.Error("error : %v", err)
+               return err
+       }
+       a1.Logger.Debug(" created metadata %v", createdmetadata)
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       creation_metadata := createdmetadata[instanceMetadataKey]
+       var metadata map[string]interface{}
+       if err = json.Unmarshal([]byte(creation_metadata.(string)), &metadata); err != nil {
+               a1.Logger.Error("unmarshal error : %v", err)
+               return err
+       }
+
+       a1.Logger.Debug(" created metadata created_at %v", metadata["created_at"])
+       creation_timestamp := metadata["created_at"]
+
+       rh.deleteMetadata(policyTypeId, policyInstanceID)
+
+       rh.deleteInstancedata(policyTypeId, policyInstanceID)
+
+       rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string))
+
+       message := rmr.Message{}
+       rmrMessage, err1 := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE")
+       if err1 != nil {
+               a1.Logger.Error("error : %v", err1)
+               return err1
+       }
+       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest)
+       if isSent {
+               a1.Logger.Debug("rmrSendToXapp : message sent")
+       } else {
+               //TODO:if message not sent need to return error or just log it or retry sending
+               a1.Logger.Error("rmrSendToXapp : message not sent")
+       }
+
+       return nil
+}
+
+func (rh *Resthook) DataDelivery(httpBody interface{}) error {
+       a1.Logger.Debug("httpbody : %+v", httpBody)
+       mymap := httpBody.(map[string]interface{})
+       message := rmr.Message{}
+       rmrMessage, err := message.A1EIMessage(mymap["job"].(string), mymap["payload"].(string))
+       if err != nil {
+               a1.Logger.Error("error : %v", err)
+               return err
+       }
+       a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage)
+       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery)
+       if isSent {
+               a1.Logger.Debug("rmrSendToXapp : message sent")
+       } else {
+               a1.Logger.Error("rmrSendToXapp : message not sent")
+       }
+       return nil
+}