Reduce code redundancy in controller exception handling.
Raise exception on ID mismatch in create policy type request.
Add test of ID mismatch case.
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
Change-Id: I2c020f41d65b7ddadd71185fafb16cf2c4557a88
COPY --from=nexus3.o-ran-sc.org:10002/o-ran-sc/bldr-alpine3-rmr:4.0.2 /usr/local/lib64/librmr* /usr/local/lib64/
# copies
+COPY setup.py tox.ini /tmp/
COPY a1/ /tmp/a1
COPY tests/ /tmp/tests
-COPY setup.py tox.ini /tmp/
WORKDIR /tmp
# Run the unit tests but skip doc
mdc_logger = Logger(name=__name__)
+def _log_build_http_resp(exception, http_resp_code):
+ """
+ helper method that logs the exception and returns a tuple of (str, int) as a http response
+ """
+ msg = repr(exception)
+ mdc_logger.warning("Request failed, returning {0}: {1}".format(http_resp_code, msg))
+ return msg, http_resp_code
+
+
def _try_func_return(func):
"""
helper method that runs the function and returns a detailed http response if an exception is raised.
"""
try:
return func()
- except (ValidationError, exceptions.PolicyTypeAlreadyExists, exceptions.CantDeleteNonEmptyType) as exc:
- msg = repr(exc)
- mdc_logger.warning("Request failed, returning 400: {0}".format(msg))
- return msg, 400
+ except (ValidationError, exceptions.PolicyTypeAlreadyExists, exceptions.PolicyTypeIdMismatch, exceptions.CantDeleteNonEmptyType) as exc:
+ return _log_build_http_resp(exc, 400)
except (exceptions.PolicyTypeNotFound, exceptions.PolicyInstanceNotFound) as exc:
- msg = repr(exc)
- mdc_logger.warning("Request failed, returning 404: {0}".format(msg))
- return msg, 404
+ return _log_build_http_resp(exc, 404)
except (RejectedByBackend, NotConnected, BackendError) as exc:
"""
These are SDL errors. At the time of development here, we do not have a good understanding
For now, we log, and 503, and investigate the logs later to improve the handling/reporting.
"""
# mdc_logger.exception(exc) # waiting for https://jira.o-ran-sc.org/browse/RIC-39
- msg = repr(exc)
- mdc_logger.warning("Request failed, returning 503: {0}".format(msg))
- return msg, 503
-
+ return _log_build_http_resp(exc, 503)
# let other types of unexpected exceptions blow up and log
from threading import Thread
from mdclogpy import Logger
from ricxappframe.xapp_sdl import SDLWrapper
-from a1.exceptions import PolicyTypeNotFound, PolicyInstanceNotFound, PolicyTypeAlreadyExists, CantDeleteNonEmptyType
+from a1.exceptions import PolicyTypeNotFound, PolicyInstanceNotFound, PolicyTypeAlreadyExists, PolicyTypeIdMismatch, CantDeleteNonEmptyType
# constants
INSTANCE_DELETE_NO_RESP_TTL = int(os.environ.get("INSTANCE_DELETE_NO_RESP_TTL", 5))
check that a type is valid
"""
if SDL.get(A1NS, _generate_type_key(policy_type_id)) is None:
- raise PolicyTypeNotFound()
+ raise PolicyTypeNotFound(policy_type_id)
def _instance_is_valid(policy_type_id, policy_instance_id):
"""
_type_is_valid(policy_type_id)
if SDL.get(A1NS, _generate_instance_key(policy_type_id, policy_instance_id)) is None:
- raise PolicyInstanceNotFound
+ raise PolicyInstanceNotFound(policy_type_id)
def _get_statuses(policy_type_id, policy_instance_id):
"""
store a policy type if it doesn't already exist
"""
+ if policy_type_id != body['policy_type_id']:
+ raise PolicyTypeIdMismatch("{0} vs. {1}".format(policy_type_id, body['policy_type_id']))
key = _generate_type_key(policy_type_id)
if SDL.get(A1NS, key) is not None:
- raise PolicyTypeAlreadyExists()
- # overwrite ID in body to enforce consistency
- body['policy_type_id'] = policy_type_id
+ raise PolicyTypeAlreadyExists(policy_type_id)
SDL.set(A1NS, key, body)
if pil == []: # empty, can delete
SDL.delete(A1NS, _generate_type_key(policy_type_id))
else:
- raise CantDeleteNonEmptyType()
+ raise CantDeleteNonEmptyType(policy_type_id)
def get_policy_type(policy_type_id):
"""
-class CantDeleteNonEmptyType(BaseException):
+class A1Error(Exception):
+ """A base class for A1 exceptions."""
+
+ def __init__(self, message):
+ # Call the base class constructor with the parameters it needs
+ super(A1Error, self).__init__(message)
+
+
+class CantDeleteNonEmptyType(A1Error):
"""tried to delete a type that isn't empty"""
-class PolicyInstanceNotFound(BaseException):
+class PolicyInstanceNotFound(A1Error):
"""a policy instance cannot be found"""
-class PolicyTypeNotFound(BaseException):
+class PolicyTypeNotFound(A1Error):
"""a policy type instance cannot be found"""
-class PolicyTypeAlreadyExists(BaseException):
+class PolicyTypeAlreadyExists(A1Error):
"""a policy type already exists and replace not supported at this time"""
+
+
+class PolicyTypeIdMismatch(A1Error):
+ """a policy type request path ID differs from its body ID"""
:depth: 3
:local:
-[2.1.8] - 2020-04-29
+[2.1.8] - 2020-04-30
--------------------
* Revise Dockerfile to set user as owner of .local dir with a1 package
-* Rename console shell start script to run-a1 from run.py
+* Rename console shell start script to run-a1 from run.py
* Extend start script to report webserver listening port
* Add tiny RMR routing table for use in demo and test
* Extend documentation for running a container locally
* Add documentation of start/init parameters to _RmrLoop class
* Add new environment variable USE_FAKE_SDL (`RIC-351 <https://jira.o-ran-sc.org/browse/RIC-351>`_)
+* Respond with error if policy type ID differs from ID in object on create
[2.1.7] - 2020-04-28
monkeypatch.setattr("a1.data.SDL.set", monkey_set)
- res = client.put("/a1-p/policytypes/111", json=adm_type_good)
- assert res.status_code == 503
- res = client.put("/a1-p/policytypes/112", json=adm_type_good)
- assert res.status_code == 503
- res = client.put("/a1-p/policytypes/113", json=adm_type_good)
- assert res.status_code == 503
+ def create_alt_id(json, id):
+ """
+ Overwrites the json's policy type ID, attempts create and tests for 503
+ """
+ json['policy_type_id'] = id
+ url = "/a1-p/policytypes/{0}".format(id)
+ res = client.put(url, json=json)
+ assert res.status_code == 503
+
+ create_alt_id(adm_type_good, 111)
+ create_alt_id(adm_type_good, 112)
+ create_alt_id(adm_type_good, 113)
def test_illegal_types(client, adm_type_good):
"""
Test illegal types
"""
+ # below valid range
res = client.put("/a1-p/policytypes/0", json=adm_type_good)
assert res.status_code == 400
+ # ID mismatch
+ res = client.put("/a1-p/policytypes/1", json=adm_type_good)
+ assert res.status_code == 400
+ # above valid range
res = client.put("/a1-p/policytypes/2147483648", json=adm_type_good)
assert res.status_code == 400