Delete Policy Instance API feature. 69/9469/4
authornaman.gupta <naman.gupta@samsung.com>
Wed, 2 Nov 2022 16:15:05 +0000 (21:45 +0530)
committernaman.gupta <naman.gupta@samsung.com>
Fri, 4 Nov 2022 10:38:24 +0000 (16:08 +0530)
Implementation of Deletion of Policy Instance API

Signed-off-by: naman.gupta <naman.gupta@samsung.com>
Change-Id: Id20356cd9fa8d9138d965e96d23de4e76b8c98be

a1-go/pkg/restful/restful.go
a1-go/pkg/resthooks/resthooks.go
a1-go/pkg/resthooks/resthooks_test.go
a1-go/pkg/resthooks/types.go

index 17d1fad..b0663dd 100644 (file)
@@ -133,6 +133,19 @@ func (r *Restful) setupHandler() *operations.A1API {
                return a1_mediator.NewA1ControllerGetPolicyInstanceStatusServiceUnavailable()
        })
 
+       api.A1MediatorA1ControllerDeletePolicyInstanceHandler = a1_mediator.A1ControllerDeletePolicyInstanceHandlerFunc(func(params a1_mediator.A1ControllerDeletePolicyInstanceParams) middleware.Responder {
+               a1.Logger.Debug("handler for delete policy instance")
+               if err := r.rh.DeletePolicyInstance(models.PolicyTypeID(params.PolicyTypeID), models.PolicyInstanceID(params.PolicyInstanceID)); err != nil {
+                       if r.rh.CanPolicyInstanceBeDeleted(err) {
+                               return a1_mediator.NewA1ControllerDeletePolicyInstanceNotFound()
+                       }
+                       return a1_mediator.NewA1ControllerDeletePolicyInstanceServiceUnavailable()
+               }
+
+               return a1_mediator.NewA1ControllerDeletePolicyInstanceAccepted()
+
+       })
+       
        return api
 
 }
index 0c870f6..e0060f1 100644 (file)
@@ -51,6 +51,11 @@ 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
@@ -372,7 +377,7 @@ func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, polic
                }
 
                message := rmr.Message{}
-               rmrMessage, err := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation)
+               rmrMessage, err = message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation)
                if err != nil {
                        a1.Logger.Error("error : %v", err)
                        return err
@@ -575,3 +580,104 @@ func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, po
        }
        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, err = message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE")
+       if err != nil {
+               a1.Logger.Error("error : %v", err)
+               return err
+       }
+       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage)
+       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
+}
index 34bf97a..deffc4b 100644 (file)
@@ -225,6 +225,76 @@ func TestGetPolicyInstanceStatus(t *testing.T) {
        sdlInst.AssertExpectations(t)
 }
 
+func TestDeletePolicyInstance(t *testing.T) {
+       var policyTypeId models.PolicyTypeID
+       policyTypeId = 20001
+       var policyInstanceID models.PolicyInstanceID
+       policyInstanceID = "123456"
+       var policyTypeSchema models.PolicyTypeSchema
+       name := "admission_control_policy_mine"
+       policyTypeSchema.Name = &name
+       policytypeid := int64(20001)
+       policyTypeSchema.PolicyTypeID = &policytypeid
+       description := "various parameters to control admission of dual connection"
+       policyTypeSchema.Description = &description
+       schema := `{"$schema": "http://json-schema.org/draft-07/schema#","type":"object","properties": {"enforce": {"type":"boolean","default":"true",},"window_length": {"type":        "integer","default":1,"minimum":1,"maximum":60,"description": "Sliding window length (in minutes)",},
+"blocking_rate": {"type":"number","default":10,"minimum":1,"maximum":100,"description": "% Connections to block",},"additionalProperties": false,},}`
+       policyTypeSchema.CreateSchema = schema
+
+       key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
+       var policytypekeys [1]string
+       policytypekeys[0] = key
+
+       sdlInst.On("Get", a1MediatorNs, policytypekeys[:]).Return(map[string]interface{}{key: policyTypeSchema}, nil)
+
+       httpBody := `{
+               "enforce":true,
+               "window_length":20,
+          "blocking_rate":20,
+               "trigger_threshold":10
+               }`
+       instancekey := a1InstancePrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
+       var instancekeys [1]string
+       instancekeys[0] = instancekey
+
+       sdlInst.On("Get", a1MediatorNs, instancekeys[:]).Return(httpBody, nil)
+
+       var instanceMetadataKeys [1]string
+       instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       instanceMetadataKeys[0] = instanceMetadataKey
+       httpBody = `{
+               "created_at":"2022-11-02 10:30:20",
+                       "instance_status":"NOT IN EFFECT"
+               }`
+
+       sdlInst.On("Get", a1MediatorNs, instanceMetadataKeys[:]).Return(httpBody, nil)
+
+       sdlInst.On("Remove", a1MediatorNs, instanceMetadataKeys[:]).Return(nil)
+
+       var metadatainstancekeys [1]string
+       metadatainstancekeys[0] = instancekey
+
+       sdlInst.On("Remove", a1MediatorNs, metadatainstancekeys[:]).Return(nil)
+
+       metadatainstancekey := a1InstanceMetadataPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
+       deleted_timestamp := time.Now()
+       var metadatajson interface{}
+       metadatajson = map[string]string{"created_at": "2022-11-02 10:30:20", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "True"}
+       metadata, _ := json.Marshal(metadatajson)
+       metadatainstancearr := []interface{}{metadatainstancekey, string(metadata)}
+
+       sdlInst.On("Set", "A1m_ns", metadatainstancearr).Return(nil)
+
+       httpBodyString := `{"operation":"DELETE","payload":"","policy_instance_id":"123456","policy_type_id":"20001"}`
+
+       rmrSenderInst.On("RmrSendToXapp", httpBodyString).Return(true)
+
+       errresp := rh.DeletePolicyInstance(policyTypeId, policyInstanceID)
+
+       assert.Nil(t, errresp)
+       sdlInst.AssertExpectations(t)
+}
+
 type SdlMock struct {
        mock.Mock
 }
@@ -255,7 +325,7 @@ func (s *SdlMock) Get(ns string, keys []string) (map[string]interface{}, error)
                key = a1PolicyPrefix + strconv.FormatInt((policytypeid), 10)
        } else if keys[0] == "a1.policy_inst_metadata.20001.123456" {
                policySchemaString = `{
-                       "created_at":"0001-01-01T00:00:00.000Z",
+                       "created_at":"2022-11-02 10:30:20",
                        "instance_status":"NOT IN EFFECT"
                        }`
                key = a1InstanceMetadataPrefix + strconv.FormatInt(policytypeid, 10) + "." + string(policyInstanceID)
index 4765e29..2eb2f6d 100644 (file)
@@ -22,6 +22,7 @@ package resthooks
 
 import (
        "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/rmr"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 )
 
 type Resthook struct {