except ValidationError as e:
raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
- def show(self, session, _id, api_req=False):
+ def show(self, session, _id, filter_q=None, api_req=False):
"""
Get complete information on an topic
:param session: contains "username", "admin", "force", "public", "project_id", "set_project"
:param _id: server internal id or username
+ :param filter_q: dict: query parameter
:param api_req: True if this call is serving an external API request. False if serving internal request.
:return: dictionary, raise exception if not found.
"""
except ValidationError as e:
raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
- def show(self, session, _id, api_req=False):
+ def show(self, session, _id, filter_q=None, api_req=False):
"""
Get complete information on an topic
:param session: contains "username", "admin", "force", "public", "project_id", "set_project"
:param _id: server internal id
+ :param filter_q: dict: query parameter
:param api_req: True if this call is serving an external API request. False if serving internal request.
:return: dictionary, raise exception if not found.
"""
final_content["permissions"]["admin"] = False
return None
- def show(self, session, _id, api_req=False):
+ def show(self, session, _id, filter_q=None, api_req=False):
"""
Get complete information on an topic
:param session: contains "username", "admin", "force", "public", "project_id", "set_project"
:param _id: server internal id
+ :param filter_q: dict: query parameter
:param api_req: True if this call is serving an external API request. False if serving internal request.
:return: dictionary, raise exception if not found.
"""
# Projection was moved to child classes
return data
- def show(self, session, _id, api_req=False):
+ def show(self, session, _id, filter_q=None, api_req=False):
"""
Get complete information on an topic
:param session: contains "username", "admin", "force", "public", "project_id", "set_project"
:param _id: server internal id
+ :param filter_q: dict: query parameter
:param api_req: True if this call is serving an external API request. False if serving internal request.
:return: dictionary, raise exception if not found.
"""
:return: The list, it can be empty if no one match the filter_q.
"""
if topic not in self.map_topic:
- raise EngineException(
- "Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR
- )
+ raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
return self.map_topic[topic].list(session, filter_q, api_req)
- def get_item(self, session, topic, _id, api_req=False):
+ def get_item(self, session, topic, _id, filter_q=None, api_req=False):
"""
Get complete information on an item
:param session: contains the used login username and working project
:param topic: it can be: users, projects, vnfds, nsds,
:param _id: server id of the item
+ :param filter_q: other arguments
:param api_req: True if this call is serving an external API request. False if serving internal request.
:return: dictionary, raise exception if not found.
"""
if topic not in self.map_topic:
- raise EngineException(
- "Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR
- )
- return self.map_topic[topic].show(session, _id, api_req)
+ raise EngineException("Unknown topic {}!!!".format(topic), HTTPStatus.INTERNAL_SERVER_ERROR)
+ return self.map_topic[topic].show(session, _id, filter_q, api_req)
def get_file(self, session, topic, _id, path=None, accept_header=None):
"""
return vnfr_descriptor
+ def vca_status_refresh(self, session, ns_instance_content, filter_q):
+ """
+ vcaStatus in ns_instance_content maybe stale, check if it is stale and create lcm op
+ to refresh vca status by sending message to LCM when it is stale. Ignore otherwise.
+ :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
+ :param ns_instance_content: ns instance content
+ :param filter_q: dict: query parameter containing vcaStatus-refresh as true or false
+ :return: None
+ """
+ time_now, time_delta = time(), time() - ns_instance_content["_admin"]["modified"]
+ force_refresh = isinstance(filter_q, dict) and filter_q.get('vcaStatusRefresh') == 'true'
+ threshold_reached = time_delta > 120
+ if force_refresh or threshold_reached:
+ operation, _id = "vca_status_refresh", ns_instance_content["_id"]
+ ns_instance_content["_admin"]["modified"] = time_now
+ self.db.set_one(self.topic, {"_id": _id}, ns_instance_content)
+ nslcmop_desc = NsLcmOpTopic._create_nslcmop(_id, operation, None)
+ self.format_on_new(nslcmop_desc, session["project_id"], make_public=session["public"])
+ nslcmop_desc["_admin"].pop("nsState")
+ self.msg.write("ns", operation, nslcmop_desc)
+ return
+
+ def show(self, session, _id, filter_q=None, api_req=False):
+ """
+ Get complete information on an ns instance.
+ :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
+ :param _id: string, ns instance id
+ :param filter_q: dict: query parameter containing vcaStatusRefresh as true or false
+ :param api_req: True if this call is serving an external API request. False if serving internal request.
+ :return: dictionary, raise exception if not found.
+ """
+ ns_instance_content = super().show(session, _id, api_req)
+ self.vca_status_refresh(session, ns_instance_content, filter_q)
+ return ns_instance_content
+
def edit(self, session, _id, indata=None, kwargs=None, content=None):
raise EngineException(
"Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
if item == "reports":
# TODO check that project_id (_id in this context) has permissions
_id = args[0]
- outdata = self.engine.get_item(
- engine_session, engine_topic, _id, True
- )
+ filter_q = None
+ if "vcaStatusRefresh" in kwargs:
+ filter_q = {"vcaStatusRefresh": kwargs["vcaStatusRefresh"]}
+ outdata = self.engine.get_item(engine_session, engine_topic, _id, filter_q, True)
elif method == "POST":
cherrypy.response.status = HTTPStatus.CREATED.value
except aiohttp.client_exceptions.ClientConnectorError as e:
raise EngineException("Connection to '{}'Failure: {}".format(self.url, e))
- def show(self, session, ns_id, api_req=False):
+ def show(self, session, ns_id, filter_q=None, api_req=False):
metrics_list = self._get_vnf_metric_list(ns_id)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
##
import unittest
-from unittest.mock import Mock, mock_open # patch, MagicMock
+from time import time
+from unittest.mock import Mock, mock_open # patch, MagicMock
from osm_common.dbbase import DbException
from osm_nbi.engine import EngineException
from osm_common.dbmemory import DbMemory
self.assertTrue(e.exception.http_code == expect_code)
if expect_text_list:
for expect_text in expect_text_list:
- self.assertIn(
- expect_text,
- str(e.exception).lower(),
- "Expected '{}' at exception text".format(expect_text),
- )
+ self.assertIn(expect_text, str(e.exception).lower(),
+ "Expected '{}' at exception text".format(expect_text))
+
+ def test_show_instance(self):
+ session = {"force": False, "admin": False, "public": False, "project_id": [self.nsd_project], "method": "write"}
+ filter_q = {}
+ for refresh_status in ("true", "false"):
+ self.db.create_list("nsrs", yaml.load(db_nsrs_text, Loader=yaml.Loader))
+ actual_nsr = self.db.get_list("nsrs")[0]
+ nsr_id = actual_nsr["_id"]
+ filter_q['vcaStatus-refresh'] = refresh_status
+ expected_nsr = self.nsr_topic.show(session, nsr_id, filter_q=filter_q)
+ self.nsr_topic.delete(session, nsr_id)
+ actual_nsr.pop("_admin")
+ expected_nsr.pop("_admin")
+ self.assertEqual(expected_nsr, actual_nsr, "Database nsr and show() nsr do not match.")
+
+ def test_vca_status_refresh(self):
+ session = {"force": False, "admin": False, "public": False, "project_id": [self.nsd_project], "method": "write"}
+ filter_q = {'vcaStatus-refresh': 'true'}
+ time_delta = 120
+ self.db.create_list("nsrs", yaml.load(db_nsrs_text, Loader=yaml.Loader))
+ nsr = self.db.get_list("nsrs")[0]
+
+ # When vcaStatus-refresh is true
+ filter_q['vcaStatus-refresh'] = "true"
+ self.nsr_topic.vca_status_refresh(session, nsr, filter_q)
+ msg_args = self.msg.write.call_args[0]
+ self.assertEqual(msg_args[1], "vca_status_refresh", "Wrong message action")
+ self.assertGreater(nsr["_admin"]["modified"], time() - time_delta)
+
+ # When vcaStatus-refresh is false but modified time is within threshold
+ filter_q['vcaStatus-refresh'] = "false"
+ time_now = time()
+ nsr["_admin"]["modified"] = time_now
+ self.nsr_topic.vca_status_refresh(session, nsr, filter_q)
+ msg_args = self.msg.write.call_args[1]
+ self.assertEqual(msg_args, {}, "Message should not be sent.")
+ self.assertEqual(nsr["_admin"]["modified"], time_now, "Modified time should not be changed.")
+
+ # When vcaStatus-refresh is false but modified time is less than threshold
+ filter_q['vcaStatus-refresh'] = "false"
+ nsr["_admin"]["modified"] = time() - (2*time_delta)
+ self.nsr_topic.vca_status_refresh(session, nsr, filter_q)
+ msg_args = self.msg.write.call_args[0]
+ self.assertEqual(msg_args[1], "vca_status_refresh", "Wrong message action")
+ self.nsr_topic.delete(session, nsr["_id"])
+ self.assertGreater(nsr["_admin"]["modified"], time() - time_delta, "Modified time is not changed.")
def test_delete_ns(self):
self.db.create_list("nsrs", yaml.load(db_nsrs_text, Loader=yaml.Loader))