From dd7944b7069298a8c162c5dd0be6b7c9defd231d Mon Sep 17 00:00:00 2001 From: "naman.gupta" Date: Wed, 26 Oct 2022 14:38:04 +0530 Subject: [PATCH] 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 Change-Id: I1cd0cf9ad9518e31b9e0d90fddc56f85cd5848d6 --- a1-go/pkg/restful/restful.go | 11 +++++ a1-go/pkg/resthooks/resthooks.go | 84 +++++++++++++++++++++++++++++++++++ a1-go/pkg/resthooks/resthooks_test.go | 32 +++++++++++-- tox.ini | 4 +- 4 files changed, 126 insertions(+), 5 deletions(-) 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 @@ func (r *Restful) setupHandler() *operations.A1API { }) + 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 @@ func (rh *Resthook) DeletePolicyType(policyTypeId models.PolicyTypeID) error { } 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 @@ func TestDeletePolicyType(t *testing.T) { 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) GetAll(ns string) ([]string, error) { 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 @@ func (s *SdlMock) Get(ns string, keys []string) (map[string]interface{}, error) } 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 @@ func (s *SdlMock) Get(ns string, keys []string) (map[string]interface{}, error) 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 @@ commands = sh -c 'pip freeze > requirements.txt' # 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 @@ commands = whitelist_externals = echo [testenv:docs-linkcheck] -basepython = python3.7 +basepython = python3 deps = sphinx sphinx-rtd-theme sphinxcontrib-httpdomain -- 2.16.6