Implemented Retrieval of Policy instance status

Implemented Get Policy instance status API and resolving issue of python
build error in a1 python implementation.

Signed-off-by: naman.gupta <naman.gupta@samsung.com>
Change-Id: I1cd0cf9ad9518e31b9e0d90fddc56f85cd5848d6
diff --git a/a1-go/pkg/restful/restful.go b/a1-go/pkg/restful/restful.go
index 91b9659..17d1fad 100644
--- a/a1-go/pkg/restful/restful.go
+++ b/a1-go/pkg/restful/restful.go
@@ -122,6 +122,17 @@
 
 	})
 
+	api.A1MediatorA1ControllerGetPolicyInstanceStatusHandler = a1_mediator.A1ControllerGetPolicyInstanceStatusHandlerFunc(func(params a1_mediator.A1ControllerGetPolicyInstanceStatusParams) middleware.Responder {
+		a1.Logger.Debug("handler for get policy instance status")
+		if resp, err := r.rh.GetPolicyInstanceStatus(models.PolicyTypeID(params.PolicyTypeID), models.PolicyInstanceID(params.PolicyInstanceID)); err == nil {
+			return a1_mediator.NewA1ControllerGetPolicyInstanceStatusOK().WithPayload(resp)
+		}
+		if r.rh.IsPolicyInstanceNotFound(err) {
+			return a1_mediator.NewA1ControllerGetPolicyInstanceStatusNotFound()
+		}
+		return a1_mediator.NewA1ControllerGetPolicyInstanceStatusServiceUnavailable()
+	})
+
 	return api
 
 }
diff --git a/a1-go/pkg/resthooks/resthooks.go b/a1-go/pkg/resthooks/resthooks.go
index 8d30b3d..6d9ad29 100644
--- a/a1-go/pkg/resthooks/resthooks.go
+++ b/a1-go/pkg/resthooks/resthooks.go
@@ -484,3 +484,87 @@
 	}
 	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
+	}
+}
+
+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
+	}
+}
+
+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)
+	if err != nil && err == policyInstanceNotFoundError || err == policyTypeNotFoundError {
+		policyInstanceStatus.InstanceStatus = "NOT IN EFFECT"
+		return &policyInstanceStatus, err
+	}
+	policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{}
+	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
+}
diff --git a/a1-go/pkg/resthooks/resthooks_test.go b/a1-go/pkg/resthooks/resthooks_test.go
index 45e7666..34bf97a 100644
--- a/a1-go/pkg/resthooks/resthooks_test.go
+++ b/a1-go/pkg/resthooks/resthooks_test.go
@@ -203,6 +203,28 @@
 	sdlInst.AssertExpectations(t)
 }
 
+func TestGetPolicyInstanceStatus(t *testing.T) {
+	var policyTypeId models.PolicyTypeID
+	policyTypeId = 20001
+	var policyInstanceID models.PolicyInstanceID
+	policyInstanceID = "123456"
+	httpBody := `{
+		"created_at":"0001-01-01T00:00:00.000Z",
+		"instance_status":"NOT IN EFFECT"
+		}`
+	instancekey := a1InstanceMetadataPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
+	a1.Logger.Debug("httpBody String : %+v", httpBody)
+	a1.Logger.Debug("key   : %+v", instancekey)
+	var keys [1]string
+	keys[0] = instancekey
+	sdlInst.On("Get", a1MediatorNs, keys[:]).Return(httpBody)
+
+	resp := rh.GetPolicyInstanceStatus(policyTypeId, policyInstanceID)
+
+	assert.NotNil(t, resp)
+	sdlInst.AssertExpectations(t)
+}
+
 type SdlMock struct {
 	mock.Mock
 }
@@ -215,7 +237,7 @@
 func (s *SdlMock) Get(ns string, keys []string) (map[string]interface{}, error) {
 	a1.Logger.Debug("Get Called ")
 	args := s.MethodCalled("Get", ns, keys)
-	a1.Logger.Debug("keys :%+v", args.Get(1))
+	a1.Logger.Debug("ns :%+v", args.Get(0))
 	policytypeid := int64(20001)
 	policyInstanceID := "123456"
 	var policySchemaString string
@@ -231,6 +253,12 @@
 	} else if keys[0] == "a1.policy_type.20001" {
 		policySchemaString = `{"create_schema":{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"additionalProperties":false,"blocking_rate":{"default":10,"description":"% Connections to block","maximum":1001,"minimum":1,"type":"number"},"enforce":{"default":"true","type":"boolean"},"window_length":{"default":1,"description":"Sliding window length (in minutes)","maximum":60,"minimum":1,"type":"integer"}},"type":"object"},"description":"various parameters to control admission of dual connection","name":"admission_control_policy_mine","policy_type_id":20001}`
 		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",
+			"instance_status":"NOT IN EFFECT"
+			}`
+		key = a1InstanceMetadataPrefix + strconv.FormatInt(policytypeid, 10) + "." + string(policyInstanceID)
 	}
 	a1.Logger.Debug(" policy SchemaString %+v", policySchemaString)
 	policyTypeSchema, _ := json.Marshal((policySchemaString))
@@ -239,10 +267,8 @@
 	a1.Logger.Debug(" key for policy type %+v", key)
 	mp := map[string]interface{}{key: string(policySchemaString)}
 	a1.Logger.Debug("Get Called and mp return %+v ", mp)
-
 	return mp, nil
 }
-
 func (s *SdlMock) SetIfNotExists(ns string, key string, data interface{}) (bool, error) {
 	args := s.MethodCalled("SetIfNotExists", ns, key, data)
 	return args.Bool(0), args.Error(1)
diff --git a/tox.ini b/tox.ini
index 760b7a3..e305c60 100644
--- a/tox.ini
+++ b/tox.ini
@@ -61,7 +61,7 @@
 
 # verbatim as asked for by the docs instructions: https://wiki.o-ran-sc.org/display/DOC/Configure+Repo+for+Documentation
 [testenv:docs]
-basepython = python3.7
+basepython = python3
 deps =
     sphinx
     sphinx-rtd-theme
@@ -75,7 +75,7 @@
 whitelist_externals = echo
 
 [testenv:docs-linkcheck]
-basepython = python3.7
+basepython = python3
 deps = sphinx
        sphinx-rtd-theme
        sphinxcontrib-httpdomain