Releasing a new container image step 1 of 2
[ric-plt/a1.git] / pkg / resthooks / resthooks.go
index dcffe2a..803f1b7 100644 (file)
@@ -1,21 +1,23 @@
 /*
 ==================================================================================
-  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
+       Copyright (c) 2021 Samsung
 
-       http://www.apache.org/licenses/LICENSE-2.0
+        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
 
-   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.
+            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).
 
-   This source code is part of the near-RT RIC (RAN Intelligent Controller)
-   platform project (RICP).
 ==================================================================================
 */
 package resthooks
@@ -39,13 +41,14 @@ import (
 )
 
 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
+       a1PolicyPrefix                  = "a1.policy_type."
+       a1MediatorNs                    = "A1m_ns"
+       a1InstancePrefix                = "a1.policy_instance."
+       a1NotificationDestinationPrefix = "a1.policy_notification_destination."
+       a1InstanceMetadataPrefix        = "a1.policy_inst_metadata."
+       a1HandlerPrefix                 = "a1.policy_handler."
+       a1PolicyRequest                 = 20010
+       a1EIDataDelivery                = 20017
 )
 
 var typeAlreadyError = errors.New("Policy Type already exists")
@@ -65,7 +68,7 @@ func (rh *Resthook) CanPolicyTypeBeDeleted(err error) bool {
        return err == policyTypeCanNotBeDeletedError
 }
 
-func (rh *Resthook) IsPolicyTypePresent(err error) bool {
+func (rh *Resthook) IsPolicyTypeNotFound(err error) bool {
        return err == policyTypeNotFoundError
 }
 
@@ -102,12 +105,13 @@ func createResthook(sdlInst iSdl, rmrSenderInst rmr.IRmrSender) *Resthook {
 }
 
 func (rh *Resthook) GetA1Health() bool {
-       data, _ := rh.db.GetAll(a1MediatorNs)
-       if data != nil {
-               a1.Logger.Debug("Database connected and A1 is healthy")
-               return true
+       _, err := rh.db.GetAll("A1m_ns")
+       if err != nil {
+               a1.Logger.Error("error in connecting to the database. err: %v", err)
+               return false
        }
-       return false
+       a1.Logger.Debug("A1 is healthy")
+       return true
 }
 
 func (rh *Resthook) GetAllPolicyType() []models.PolicyTypeID {
@@ -271,7 +275,7 @@ func validate(httpBodyString string, schemaString string) bool {
        return true
 }
 
-func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) (string, error) {
+func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}, notificationDestination string) (string, error) {
        var keys [1]string
        operation := "CREATE"
        typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
@@ -291,6 +295,7 @@ func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policy
        // 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)
+       notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
        keys[0] = typekey
        instanceMap, err := rh.db.Get(a1MediatorNs, keys[:])
        if err != nil {
@@ -304,15 +309,22 @@ func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policy
                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
+               success, err := rh.db.SetIf(a1MediatorNs, instancekey, instanceMap[instancekey], string(data))
+               if err != nil {
+                       a1.Logger.Error("error2 :%+v", err)
+                       return operation, err
                }
                if !success {
                        a1.Logger.Debug("Policy instance %+v already exist", policyInstanceID)
                        return operation, InstanceAlreadyError
                }
+
+               if len(notificationDestination) > 0 {
+                       if err = rh.db.Set(a1MediatorNs, notificationDestinationkey, notificationDestination); err != nil {
+                               a1.Logger.Error("error3 :%+v", err)
+                               return operation, err
+                       }
+               }
        } else {
                data, _ := json.Marshal(httpBody)
                a1.Logger.Debug("Marshaled String : %+v", string(data))
@@ -323,10 +335,15 @@ func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policy
                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
+               if err = rh.db.Set(a1MediatorNs, instancekey, string(data)); err != nil {
+                       a1.Logger.Error("error4 :%+v", err)
+                       return operation, err
+               }
+               if len(notificationDestination) > 0 {
+                       if err := rh.db.Set(a1MediatorNs, notificationDestinationkey, notificationDestination); err != nil {
+                               a1.Logger.Error("error :%+v", err)
+                               return operation, err
+                       }
                }
        }
        a1.Logger.Debug("Policy Instance created ")
@@ -358,7 +375,7 @@ func (rh *Resthook) storePolicyInstanceMetadata(policyTypeId models.PolicyTypeID
        return true, nil
 }
 
-func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) error {
+func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}, notificationDestination string) error {
        a1.Logger.Debug("CreatePolicyInstance function")
        //  validate the PUT against the schema
        var policyTypeSchema *models.PolicyTypeSchema
@@ -378,7 +395,7 @@ func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, polic
        isvalid := validate(httpBodyString, schemaString)
        if isvalid {
                var operation string
-               operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody)
+               operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody, notificationDestination)
                if err != nil {
                        a1.Logger.Error("error :%+v", err)
                        return err
@@ -399,7 +416,7 @@ func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, polic
                        a1.Logger.Error("error : %v", err)
                        return err
                }
-               isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest)
+               isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
                if isSent {
                        a1.Logger.Debug("rmrSendToXapp : message sent")
                } else {
@@ -414,7 +431,7 @@ func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, polic
        return nil
 }
 
-func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (interface{}, error) {
+func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) {
        a1.Logger.Debug("GetPolicyInstance1")
 
        var keys [1]string
@@ -427,17 +444,17 @@ func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyIn
        valmap, err := rh.db.Get(a1MediatorNs, keys[:])
        if len(valmap) == 0 {
                a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
-               return "{}", policyTypeNotFoundError
+               return map[string]interface{}{}, policyTypeNotFoundError
        }
 
        if err != nil {
                a1.Logger.Error("error in retrieving policy type. err: %v", err)
-               return "{}", err
+               return map[string]interface{}{}, err
        }
 
        if valmap[typekey] == nil {
                a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
-               return "{}", policyTypeNotFoundError
+               return map[string]interface{}{}, policyTypeNotFoundError
        }
 
        a1.Logger.Debug("keysmap : %+v", valmap[typekey])
@@ -453,10 +470,15 @@ func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyIn
 
        if instanceMap[instancekey] == nil {
                a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
-               return "{}", policyInstanceNotFoundError
+               return map[string]interface{}{}, policyInstanceNotFoundError
        }
 
-       valStr := fmt.Sprint(instanceMap[instancekey])
+       var valStr map[string]interface{}
+       err = json.Unmarshal([]byte(instanceMap[instancekey].(string)), &valStr)
+       if err != nil {
+               fmt.Println("error:", err)
+       }
+       fmt.Println(valStr)
        return valStr, nil
 }
 
@@ -543,7 +565,7 @@ func (rh *Resthook) instanceValidity(policyTypeId models.PolicyTypeID, policyIns
                a1.Logger.Error("policy instance error : %v", err)
                return err
        }
-       if len(policyTypeInstances.(string)) == 0 {
+       if policyTypeInstances == nil {
                a1.Logger.Debug("policy instance Not Present  ")
                return policyInstanceNotFoundError
        }
@@ -567,18 +589,35 @@ func (rh *Resthook) getMetaData(policyTypeId models.PolicyTypeID, policyInstance
        return instanceMetadataMap, nil
 }
 
+func (rh *Resthook) getPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) {
+       instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       var keys [1]string
+       keys[0] = instancehandlerKey
+       resp, err := rh.db.Get(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("error1 :%+v", err)
+               return false, err
+       }
+       for _, key := range resp {
+               if key == "OK" {
+                       return true, nil
+               }
+       }
+       return false, 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"
+       policyInstanceStatus.EnforceStatus = "NOT_ENFORCED"
+       policyInstanceStatus.EnforceReason = "OTHER_REASON"
+       if err != nil && (err == policyInstanceNotFoundError || err == policyTypeNotFoundError) {
                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)
@@ -592,11 +631,13 @@ func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, po
                //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"
+       enforced, err := rh.getPolicyInstanceStatus(policyTypeId, policyInstanceID)
+       if err != nil || (err == nil && !enforced) {
+               a1.Logger.Error("marshal error : %v", err)
+               return &policyInstanceStatus, err
        }
+       policyInstanceStatus.EnforceStatus = "ENFORCED"
+       policyInstanceStatus.EnforceReason = ""
        return &policyInstanceStatus, nil
 }
 
@@ -632,9 +673,22 @@ func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyI
        keys[0] = instancekey
        err := rh.db.Remove(a1MediatorNs, keys[:])
        if err != nil {
-               a1.Logger.Error("error in deleting policy type err: %v", err)
+               a1.Logger.Error("error in deleting policy instance err: %v", err)
+               return err
+       }
+       return nil
+}
+
+func (rh *Resthook) deleteNotificationDestination(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error {
+       var keys [1]string
+       notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
+       keys[0] = notificationDestinationkey
+       err := rh.db.Remove(a1MediatorNs, keys[:])
+       if err != nil {
+               a1.Logger.Error("error in deleting notificationDestination err: %v", err)
                return err
        }
+
        return nil
 }
 
@@ -670,7 +724,10 @@ func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, polic
        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 {
+       creation_metadata_string := creation_metadata.(string)
+       creation_metadata_string = strings.TrimRight(creation_metadata_string, "]")
+       creation_metadata_string = strings.TrimLeft(creation_metadata_string, "[")
+       if err = json.Unmarshal([]byte(creation_metadata_string), &metadata); err != nil {
                a1.Logger.Error("unmarshal error : %v", err)
                return err
        }
@@ -682,6 +739,8 @@ func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, polic
 
        rh.deleteInstancedata(policyTypeId, policyInstanceID)
 
+       rh.deleteNotificationDestination(policyTypeId, policyInstanceID)
+
        rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string))
 
        message := rmr.Message{}
@@ -690,7 +749,7 @@ func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, polic
                a1.Logger.Error("error : %v", err1)
                return err1
        }
-       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest)
+       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest, int(policyTypeId))
        if isSent {
                a1.Logger.Debug("rmrSendToXapp : message sent")
        } else {
@@ -711,7 +770,7 @@ func (rh *Resthook) DataDelivery(httpBody interface{}) error {
                return err
        }
        a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage)
-       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery)
+       isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery, rmr.DefaultSubId)
        if isSent {
                a1.Logger.Debug("rmrSendToXapp : message sent")
        } else {