Merge "Fix API pagination problem in multi servers"
This commit is contained in:
commit
c65931ceab
|
@ -44,7 +44,8 @@ class ViewBuilder(base.BaseViewBuilder):
|
|||
def _basic_subscription_info(self, vnf_lcm_subscription, filter=None):
|
||||
if filter is None:
|
||||
if 'filter' in vnf_lcm_subscription:
|
||||
filter_dict = {}
|
||||
filter_dict = json.loads(
|
||||
vnf_lcm_subscription.filter)
|
||||
|
||||
if 'filter' in vnf_lcm_subscription.filter:
|
||||
filter_dict = json.loads(
|
||||
|
|
|
@ -56,8 +56,11 @@ from tacker import manager
|
|||
from tacker import objects
|
||||
from tacker.objects import fields
|
||||
from tacker.objects.fields import ErrorPoint as EP
|
||||
from tacker.objects.vnf_instance import VnfInstanceList as vnf_instance_list
|
||||
from tacker.objects import vnf_lcm_op_occs as vnf_lcm_op_occs_obj
|
||||
from tacker.objects.vnf_lcm_op_occs import VnfLcmOpOccList as vnf_lcm_op_list
|
||||
from tacker.objects import vnf_lcm_subscriptions as subscription_obj
|
||||
from tacker.objects.vnf_lcm_subscriptions import LccnSubscriptionList as s_list
|
||||
from tacker.plugins.common import constants
|
||||
from tacker.policies import vnf_lcm as vnf_lcm_policies
|
||||
from tacker.tosca import utils as toscautils
|
||||
|
@ -192,9 +195,6 @@ class VnfLcmController(wsgi.Controller):
|
|||
self._vnfm_plugin = manager.TackerManager.get_service_plugins()['VNFM']
|
||||
self._view_builder_op_occ = vnf_op_occs_view.ViewBuilder()
|
||||
self._view_builder_subscription = vnf_subscription_view.ViewBuilder()
|
||||
self._nextpages_vnf_instances = {}
|
||||
self._nextpages_lcm_op_occs = {}
|
||||
self._nextpages_subscriptions = {}
|
||||
|
||||
def _get_vnf_instance_href(self, vnf_instance):
|
||||
return '{}vnflcm/v1/vnf_instances/{}'.format(
|
||||
|
@ -560,13 +560,6 @@ class VnfLcmController(wsgi.Controller):
|
|||
|
||||
return vnf_package_info[0]
|
||||
|
||||
def _delete_expired_nextpages(self, nextpages):
|
||||
for k, v in list(nextpages.items()):
|
||||
if timeutils.is_older_than(v['created_time'],
|
||||
CONF.vnf_lcm.nextpage_expiration_time):
|
||||
LOG.debug('Old nextpages are deleted. id: %s' % k)
|
||||
nextpages.pop(k)
|
||||
|
||||
@wsgi.response(http_client.OK)
|
||||
@wsgi.expected_errors((http_client.FORBIDDEN, http_client.NOT_FOUND))
|
||||
def show(self, request, id):
|
||||
|
@ -596,39 +589,43 @@ class VnfLcmController(wsgi.Controller):
|
|||
nextpage = request.GET.get('nextpage_opaque_marker')
|
||||
allrecords = request.GET.get('all_records')
|
||||
|
||||
limit = None
|
||||
marker_obj = None
|
||||
result = []
|
||||
|
||||
if allrecords != 'yes' and nextpage:
|
||||
self._delete_expired_nextpages(self._nextpages_vnf_instances)
|
||||
# get maximum record size per page
|
||||
if allrecords != 'yes':
|
||||
limit = CONF.vnf_lcm.vnf_instance_num
|
||||
|
||||
if nextpage in self._nextpages_vnf_instances:
|
||||
result = self._nextpages_vnf_instances.pop(
|
||||
nextpage)['nextpage']
|
||||
else:
|
||||
vnf_instances = objects.VnfInstanceList.get_by_filters(
|
||||
request.context, filters=filters)
|
||||
# get next page marker object from nextpage id
|
||||
if nextpage:
|
||||
marker_obj = objects.VnfInstance.get_by_id(request.context,
|
||||
nextpage)
|
||||
try:
|
||||
# get records from DB within maximum record size per page
|
||||
# except for getting all records case
|
||||
result = vnf_instance_list.get_by_marker_filter(request.context,
|
||||
limit, marker_obj, filters=filters)
|
||||
except Exception as e:
|
||||
LOG.exception(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
|
||||
result = self._view_builder.index(vnf_instances)
|
||||
result = self._view_builder.index(result)
|
||||
|
||||
res = webob.Response(content_type='application/json')
|
||||
res.status_int = 200
|
||||
|
||||
if (allrecords != 'yes' and
|
||||
len(result) > CONF.vnf_lcm.vnf_instance_num):
|
||||
nextpageid = uuidutils.generate_uuid()
|
||||
# if the number of records obtained from DB is equal to maximum record
|
||||
# size per page, the id of the last record is used as next page marker
|
||||
# and set it to Link header of the response
|
||||
if (allrecords != 'yes' and len(result) >= limit):
|
||||
nextpageid = result[(limit - 1)]['id']
|
||||
links = ('Link', '<%s?nextpage_opaque_marker=%s>; rel="next"' % (
|
||||
request.path_url, nextpageid))
|
||||
res.headerlist.append(links)
|
||||
res.body = jsonutils.dump_as_bytes(
|
||||
result[: CONF.vnf_lcm.vnf_instance_num])
|
||||
|
||||
self._delete_expired_nextpages(self._nextpages_vnf_instances)
|
||||
|
||||
remain = result[CONF.vnf_lcm.vnf_instance_num:]
|
||||
self._nextpages_vnf_instances.update({nextpageid:
|
||||
{'created_time': timeutils.utcnow(), 'nextpage': remain}})
|
||||
else:
|
||||
res.body = jsonutils.dump_as_bytes(result)
|
||||
res.body = jsonutils.dump_as_bytes(result)
|
||||
|
||||
return res
|
||||
|
||||
|
@ -1061,9 +1058,9 @@ class VnfLcmController(wsgi.Controller):
|
|||
@wsgi.response(http_client.OK)
|
||||
def subscription_list(self, request):
|
||||
nextpage_opaque_marker = None
|
||||
paging = 1
|
||||
filter_string = ""
|
||||
ignore_nextpages = False
|
||||
limit = None
|
||||
marker_obj = None
|
||||
subscription_data = []
|
||||
|
||||
query_params = request.query_string
|
||||
|
@ -1083,9 +1080,6 @@ class VnfLcmController(wsgi.Controller):
|
|||
filter_string = query_param_key_value[1]
|
||||
if query_param_key_value[0] == 'nextpage_opaque_marker':
|
||||
nextpage_opaque_marker = query_param_key_value[1]
|
||||
if query_param_key_value[0] == 'page':
|
||||
paging = int(query_param_key_value[1])
|
||||
ignore_nextpages = True
|
||||
|
||||
if filter_string:
|
||||
# check enumerations columns
|
||||
|
@ -1114,55 +1108,48 @@ class VnfLcmController(wsgi.Controller):
|
|||
title='Bad Request')
|
||||
|
||||
nextpage = nextpage_opaque_marker
|
||||
if allrecords != 'yes' and not ignore_nextpages and nextpage:
|
||||
self._delete_expired_nextpages(self._nextpages_subscriptions)
|
||||
|
||||
if nextpage in self._nextpages_subscriptions:
|
||||
subscription_data = self._nextpages_subscriptions.pop(
|
||||
nextpage)['nextpage']
|
||||
else:
|
||||
try:
|
||||
filter_string_parsed = self._view_builder_subscription. \
|
||||
validate_filter(filter_string)
|
||||
if nextpage_opaque_marker:
|
||||
start_index = paging - 1
|
||||
else:
|
||||
start_index = None
|
||||
try:
|
||||
filter_string_parsed = self._view_builder_subscription. \
|
||||
validate_filter(filter_string)
|
||||
|
||||
vnf_lcm_subscriptions = (
|
||||
subscription_obj.LccnSubscriptionList.
|
||||
get_by_filters(request.context,
|
||||
read_deleted='no',
|
||||
filters=filter_string_parsed,
|
||||
nextpage_opaque_marker=start_index))
|
||||
# get maximum record size per page
|
||||
if allrecords != 'yes':
|
||||
limit = CONF.vnf_lcm.subscription_num
|
||||
|
||||
LOG.debug("vnf_lcm_subscriptions %s" % vnf_lcm_subscriptions)
|
||||
subscription_data = self._view_builder_subscription. \
|
||||
subscription_list(vnf_lcm_subscriptions)
|
||||
except Exception as e:
|
||||
LOG.error(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
# get next page marker object from nextpage id
|
||||
if nextpage:
|
||||
marker_obj = objects.LccnSubscription.get_by_id(
|
||||
request.context, nextpage)
|
||||
|
||||
# get records from DB within maximum record size per page
|
||||
# except for getting all records case
|
||||
result = s_list.get_by_marker_filter(
|
||||
request.context, limit,
|
||||
marker_obj, filters=filter_string_parsed,
|
||||
read_deleted='no')
|
||||
LOG.debug("vnf_lcm_subscriptions %s" % result)
|
||||
|
||||
subscription_data = self._view_builder_subscription. \
|
||||
subscription_list(result)
|
||||
except Exception as e:
|
||||
LOG.error(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
|
||||
# make response
|
||||
res = webob.Response(content_type='application/json')
|
||||
res.status_int = 200
|
||||
|
||||
if (allrecords != 'yes' and not ignore_nextpages and
|
||||
len(subscription_data) > CONF.vnf_lcm.subscription_num):
|
||||
nextpageid = uuidutils.generate_uuid()
|
||||
# if the number of records obtained from DB is equal to maximum record
|
||||
# size per page, the id of the last record is used as next page marker
|
||||
# and set it to Link header of the response
|
||||
if (allrecords != 'yes' and len(subscription_data) >= limit):
|
||||
nextpageid = subscription_data[(limit - 1)]['id']
|
||||
links = ('Link', '<%s?nextpage_opaque_marker=%s>; rel="next"' % (
|
||||
request.path_url, nextpageid))
|
||||
res.headerlist.append(links)
|
||||
|
||||
remain = subscription_data[CONF.vnf_lcm.subscription_num:]
|
||||
subscription_data = (
|
||||
subscription_data[: CONF.vnf_lcm.subscription_num])
|
||||
|
||||
self._delete_expired_nextpages(self._nextpages_subscriptions)
|
||||
self._nextpages_subscriptions.update({nextpageid:
|
||||
{'created_time': timeutils.utcnow(), 'nextpage': remain}})
|
||||
|
||||
res.body = jsonutils.dump_as_bytes(subscription_data)
|
||||
|
||||
LOG.debug("subscription_list res %s" % res)
|
||||
|
@ -1748,52 +1735,53 @@ class VnfLcmController(wsgi.Controller):
|
|||
nextpage = request.GET.get('nextpage_opaque_marker')
|
||||
allrecords = request.GET.get('all_records')
|
||||
|
||||
limit = None
|
||||
marker_obj = None
|
||||
result = []
|
||||
|
||||
if allrecords != 'yes' and nextpage:
|
||||
self._delete_expired_nextpages(self._nextpages_lcm_op_occs)
|
||||
self._view_builder_op_occ.validate_attribute_fields(
|
||||
all_fields=all_fields, fields=fields,
|
||||
exclude_fields=exclude_fields,
|
||||
exclude_default=exclude_default)
|
||||
|
||||
if nextpage in self._nextpages_lcm_op_occs:
|
||||
result = self._nextpages_lcm_op_occs.pop(nextpage)['nextpage']
|
||||
else:
|
||||
self._view_builder_op_occ.validate_attribute_fields(
|
||||
all_fields=all_fields, fields=fields,
|
||||
exclude_fields=exclude_fields,
|
||||
exclude_default=exclude_default)
|
||||
filters = self._view_builder_op_occ.validate_filter(filters)
|
||||
|
||||
filters = self._view_builder_op_occ.validate_filter(filters)
|
||||
# get maximum record size per page
|
||||
if allrecords != 'yes':
|
||||
limit = CONF.vnf_lcm.lcm_op_occ_num
|
||||
|
||||
try:
|
||||
vnf_lcm_op_occs = (
|
||||
vnf_lcm_op_occs_obj.VnfLcmOpOccList.get_by_filters(
|
||||
request.context, read_deleted='no', filters=filters))
|
||||
except Exception as e:
|
||||
LOG.exception(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
# get next page marker object from nextpage id
|
||||
if nextpage:
|
||||
marker_obj = vnf_lcm_op_occs_obj.VnfLcmOpOcc.get_by_id(
|
||||
request.context, nextpage)
|
||||
|
||||
result = self._view_builder_op_occ.index(request, vnf_lcm_op_occs,
|
||||
all_fields=all_fields, exclude_fields=exclude_fields,
|
||||
fields=fields, exclude_default=exclude_default)
|
||||
try:
|
||||
# get records from DB within maximum record size per page
|
||||
# except for getting all records case
|
||||
result = vnf_lcm_op_list.get_by_marker_filter(request.context,
|
||||
limit, marker_obj, filters=filters, read_deleted='no')
|
||||
except Exception as e:
|
||||
LOG.exception(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
|
||||
result = self._view_builder_op_occ.index(request, result,
|
||||
all_fields=all_fields, exclude_fields=exclude_fields,
|
||||
fields=fields, exclude_default=exclude_default)
|
||||
|
||||
res = webob.Response(content_type='application/json')
|
||||
res.status_int = 200
|
||||
|
||||
if allrecords != 'yes' and len(result) > CONF.vnf_lcm.lcm_op_occ_num:
|
||||
nextpageid = uuidutils.generate_uuid()
|
||||
# if the number of records obtained from DB is equal to maximum record
|
||||
# size per page, the id of the last record is used as next page marker
|
||||
# and set it to Link header of the response
|
||||
if (allrecords != 'yes' and len(result) >= limit):
|
||||
nextpageid = result[(limit - 1)]['id']
|
||||
links = ('Link', '<%s?nextpage_opaque_marker=%s>; rel="next"' % (
|
||||
request.path_url, nextpageid))
|
||||
res.headerlist.append(links)
|
||||
res.body = jsonutils.dump_as_bytes(
|
||||
result[: CONF.vnf_lcm.lcm_op_occ_num])
|
||||
|
||||
self._delete_expired_nextpages(self._nextpages_lcm_op_occs)
|
||||
|
||||
remain = result[CONF.vnf_lcm.lcm_op_occ_num:]
|
||||
self._nextpages_lcm_op_occs.update({nextpageid:
|
||||
{'created_time': timeutils.utcnow(), 'nextpage': remain}})
|
||||
else:
|
||||
res.body = jsonutils.dump_as_bytes(result)
|
||||
res.body = jsonutils.dump_as_bytes(result)
|
||||
|
||||
return res
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ from io import BytesIO
|
|||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import traceback
|
||||
import webob
|
||||
import zipfile
|
||||
from zipfile import ZipFile
|
||||
|
@ -28,7 +29,6 @@ from oslo_log import log as logging
|
|||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from tacker._i18n import _
|
||||
|
@ -40,8 +40,10 @@ from tacker.common import exceptions
|
|||
from tacker.common import utils
|
||||
from tacker.conductor.conductorrpc import vnf_pkgm_rpc
|
||||
from tacker.glance_store import store as glance_store
|
||||
from tacker import objects
|
||||
from tacker.objects import fields
|
||||
from tacker.objects import vnf_package as vnf_package_obj
|
||||
from tacker.objects.vnf_package import VnfPackagesList as vnf_package_list
|
||||
from tacker.policies import vnf_package as vnf_package_policies
|
||||
from tacker import wsgi
|
||||
|
||||
|
@ -75,13 +77,6 @@ class VnfPkgmController(wsgi.Controller):
|
|||
raise webob.exc.HTTPNotFound(explanation=msg)
|
||||
return vnf_package
|
||||
|
||||
def _delete_expired_nextpages(self, nextpages):
|
||||
for k, v in nextpages.items():
|
||||
if timeutils.is_older_than(v['created_time'],
|
||||
CONF.vnf_package.nextpage_expiration_time):
|
||||
LOG.debug('Old nextpages are deleted. id: %s' % k)
|
||||
nextpages.pop(k)
|
||||
|
||||
@wsgi.response(http_client.CREATED)
|
||||
@wsgi.expected_errors((http_client.BAD_REQUEST, http_client.FORBIDDEN))
|
||||
@validation.schema(vnf_packages.create)
|
||||
|
@ -162,42 +157,47 @@ class VnfPkgmController(wsgi.Controller):
|
|||
filters = self._view_builder.validate_filter(filters)
|
||||
|
||||
results = []
|
||||
limit = None
|
||||
marker_obj = None
|
||||
|
||||
if allrecords != 'yes' and nextpage:
|
||||
self._delete_expired_nextpages(self._nextpages)
|
||||
if allrecords != 'yes':
|
||||
limit = CONF.vnf_package.vnf_package_num
|
||||
|
||||
if nextpage in self._nextpages:
|
||||
results = self._nextpages.pop(
|
||||
nextpage)['nextpage']
|
||||
else:
|
||||
vnf_packages = vnf_package_obj.VnfPackagesList.get_by_filters(
|
||||
request.context, read_deleted='no', filters=filters)
|
||||
# get next page marker object from nextpage id
|
||||
if nextpage:
|
||||
marker_obj = objects.VnfPackage.get_by_id(request.context,
|
||||
nextpage)
|
||||
|
||||
results = self._view_builder.index(vnf_packages,
|
||||
all_fields=all_fields,
|
||||
exclude_fields=exclude_fields,
|
||||
fields=fields,
|
||||
exclude_default=exclude_default)
|
||||
try:
|
||||
# get records from DB within maximum record size per page
|
||||
# except for getting all records case
|
||||
result = vnf_package_list.get_by_marker_filter(request.context,
|
||||
limit, marker_obj, filters=filters, read_deleted='no')
|
||||
except Exception as e:
|
||||
LOG.exception(traceback.format_exc())
|
||||
return self._make_problem_detail(
|
||||
str(e), 500, title='Internal Server Error')
|
||||
|
||||
results = self._view_builder.index(result,
|
||||
all_fields=all_fields,
|
||||
exclude_fields=exclude_fields,
|
||||
fields=fields,
|
||||
exclude_default=exclude_default)
|
||||
|
||||
res = webob.Response(content_type='application/json')
|
||||
res.status_int = 200
|
||||
|
||||
# if the number of records obtained from DB is equal to maximum record
|
||||
# size per page, the id of the last record is used as next page marker
|
||||
# and set it to Link header of the response
|
||||
if (allrecords != 'yes' and
|
||||
len(results) > CONF.vnf_package.vnf_package_num):
|
||||
nextpageid = uuidutils.generate_uuid()
|
||||
len(results) >= limit):
|
||||
nextpageid = result[(limit - 1)]['id']
|
||||
links = ('Link', '<%s?nextpage_opaque_marker=%s>; rel="next"' % (
|
||||
request.path_url, nextpageid))
|
||||
res.headerlist.append(links)
|
||||
res.body = jsonutils.dump_as_bytes(
|
||||
results[: CONF.vnf_package.vnf_package_num], default=str)
|
||||
|
||||
self._delete_expired_nextpages(self._nextpages)
|
||||
|
||||
remain = results[CONF.vnf_package.vnf_package_num:]
|
||||
self._nextpages.update({nextpageid:
|
||||
{'created_time': timeutils.utcnow(), 'nextpage': remain}})
|
||||
else:
|
||||
res.body = jsonutils.dump_as_bytes(results, default=str)
|
||||
res.body = jsonutils.dump_as_bytes(results, default=str)
|
||||
|
||||
return res
|
||||
|
||||
|
|
|
@ -55,11 +55,7 @@ OPTS = [
|
|||
cfg.IntOpt(
|
||||
'vnf_instance_num',
|
||||
default=100,
|
||||
help="Number of vnf_instances contained in 1 page"),
|
||||
cfg.IntOpt(
|
||||
'nextpage_expiration_time',
|
||||
default=3600,
|
||||
help="Expiration time (sec) for paging")]
|
||||
help="Number of vnf_instances contained in 1 page")]
|
||||
|
||||
vnf_lcm_group = cfg.OptGroup('vnf_lcm',
|
||||
title='vnf_lcm options',
|
||||
|
|
|
@ -78,10 +78,7 @@ Related options:
|
|||
help=_("List of del inputs from lower-vnfd")),
|
||||
cfg.IntOpt('vnf_package_num',
|
||||
default=100,
|
||||
help=_("Number of vnf_packages contained in 1 page")),
|
||||
cfg.IntOpt('nextpage_expiration_time',
|
||||
default=3600,
|
||||
help=_("Expiration time (sec) for paging")),
|
||||
help=_("Number of vnf_packages contained in 1 page"))
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ from tacker.common import utils
|
|||
from tacker.db import api as db_api
|
||||
from tacker.db.db_sqlalchemy import api
|
||||
from tacker.db.db_sqlalchemy import models
|
||||
from tacker.db import sqlalchemyutils
|
||||
from tacker.db.vnfm import vnfm_db
|
||||
from tacker import objects
|
||||
from tacker.objects import base
|
||||
|
@ -127,6 +128,23 @@ def _vnf_instance_list_by_filter(context, columns_to_join=None,
|
|||
return query.all()
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_instance_list_by_filter_query(context, columns_to_join=None,
|
||||
filters=None):
|
||||
query = api.model_query(context, models.VnfInstance,
|
||||
read_deleted="no",
|
||||
project_only=True)
|
||||
|
||||
if columns_to_join:
|
||||
for column in columns_to_join:
|
||||
query = query.options(joinedload(column))
|
||||
|
||||
if filters:
|
||||
query = common.apply_filters(query, filters)
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def _make_vnf_instance_list(context, vnf_instance_list, db_vnf_instance_list,
|
||||
expected_attrs):
|
||||
vnf_instance_cls = VnfInstance
|
||||
|
@ -545,6 +563,22 @@ class VnfInstanceList(ovoo_base.ObjectListBase, base.TackerObject):
|
|||
return _make_vnf_instance_list(context, cls(), db_vnf_instances,
|
||||
expected_attrs)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_marker_filter(cls, context, limit, marker_obj,
|
||||
filters=None, expected_attrs=None):
|
||||
expected_attrs = ["instantiated_vnf_info"]
|
||||
query = _vnf_instance_list_by_filter_query(context,
|
||||
columns_to_join=expected_attrs,
|
||||
filters=filters)
|
||||
query = sqlalchemyutils.paginate_query(query, model=models.VnfInstance,
|
||||
limit=limit,
|
||||
sorts=[['id', 'asc']],
|
||||
marker_obj=marker_obj)
|
||||
db_vnf_instances = query.all()
|
||||
|
||||
return _make_vnf_instance_list(context, cls(), db_vnf_instances,
|
||||
expected_attrs)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_filters(cls, context, filters=None,
|
||||
expected_attrs=None):
|
||||
|
|
|
@ -24,6 +24,7 @@ from tacker.common import utils
|
|||
from tacker.db import api as db_api
|
||||
from tacker.db.db_sqlalchemy import api
|
||||
from tacker.db.db_sqlalchemy import models
|
||||
from tacker.db import sqlalchemyutils
|
||||
from tacker import objects
|
||||
from tacker.objects import base
|
||||
from tacker.objects import common
|
||||
|
@ -151,6 +152,19 @@ def _vnf_lcm_op_occs_get_by_filters(context, read_deleted=None,
|
|||
return query.all()
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_lcm_op_occs_get_by_filters_query(context, read_deleted=None,
|
||||
filters=None):
|
||||
|
||||
query = api.model_query(context, models.VnfLcmOpOccs,
|
||||
read_deleted=read_deleted, project_only=True)
|
||||
|
||||
if filters:
|
||||
query = common.apply_filters(query, filters)
|
||||
|
||||
return query
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_notify_get_by_id(context, vnf_instance_id, columns_to_join=None):
|
||||
|
||||
|
@ -484,6 +498,19 @@ class VnfLcmOpOccList(ovoo_base.ObjectListBase, base.TackerObject):
|
|||
context, read_deleted=read_deleted, filters=filters)
|
||||
return _make_vnf_lcm_op_occs_list(context, cls(), db_vnf_lcm_op_occs)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_marker_filter(cls, context, limit,
|
||||
marker_obj, filters=None, read_deleted=None):
|
||||
query = _vnf_lcm_op_occs_get_by_filters_query(
|
||||
context, read_deleted=read_deleted, filters=filters)
|
||||
query = sqlalchemyutils.paginate_query(query,
|
||||
model=models.VnfLcmOpOccs,
|
||||
limit=limit,
|
||||
sorts=[['id', 'asc']],
|
||||
marker_obj=marker_obj)
|
||||
db_vnf_lcm_op_occs = query.all()
|
||||
return _make_vnf_lcm_op_occs_list(context, cls(), db_vnf_lcm_op_occs)
|
||||
|
||||
|
||||
@base.TackerObjectRegistry.register
|
||||
class ResourceChanges(base.TackerObject,
|
||||
|
|
|
@ -24,6 +24,7 @@ import tacker.conf
|
|||
from tacker.db import api as db_api
|
||||
from tacker.db.db_sqlalchemy import api
|
||||
from tacker.db.db_sqlalchemy import models
|
||||
from tacker.db import sqlalchemyutils
|
||||
from tacker import objects
|
||||
from tacker.objects import base
|
||||
from tacker.objects import common
|
||||
|
@ -381,6 +382,37 @@ def _vnf_lcm_subscription_list_by_filters(context,
|
|||
return query.order_by(models.VnfLcmSubscriptions.created_at).all()
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_lcm_subscription_get_query(context, read_deleted=None, filters=None):
|
||||
query = api.model_query(context, models.VnfLcmSubscriptions,
|
||||
read_deleted=read_deleted,
|
||||
project_only=True)
|
||||
binary_columns = ['notification_types', 'operation_types']
|
||||
|
||||
if filters:
|
||||
filter_data = json.dumps(filters)
|
||||
if 'ChangeNotificationsFilter' in filter_data:
|
||||
query = query.join(models.VnfLcmFilters)
|
||||
|
||||
if 'and' in filters:
|
||||
filters_and = []
|
||||
for filter in filters['and']:
|
||||
if filter['field'] in binary_columns:
|
||||
converted_value = utils.str_to_bytes(filter['value'])
|
||||
filter['value'] = converted_value
|
||||
filters_and.append(filter)
|
||||
|
||||
filters = {'and': filters_and}
|
||||
else:
|
||||
if filters['field'] in binary_columns:
|
||||
converted_value = utils.str_to_bytes(filters['value'])
|
||||
filters.update({'value': converted_value})
|
||||
|
||||
query = common.apply_filters(query, filters)
|
||||
|
||||
return query.order_by(models.VnfLcmSubscriptions.created_at)
|
||||
|
||||
|
||||
@db_api.context_manager.writer
|
||||
def _vnf_lcm_subscriptions_create(context, values, filter):
|
||||
with db_api.context_manager.writer.using(context):
|
||||
|
@ -721,6 +753,22 @@ class LccnSubscriptionList(ovoo_base.ObjectListBase, base.TackerObject):
|
|||
'objects': fields.ListOfObjectsField('LccnSubscription')
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_marker_filter(cls, context,
|
||||
limit, marker_obj,
|
||||
filters=None, read_deleted=None):
|
||||
query = _vnf_lcm_subscription_get_query(context,
|
||||
read_deleted=read_deleted,
|
||||
filters=filters)
|
||||
query = sqlalchemyutils.paginate_query(query,
|
||||
model=models.VnfLcmSubscriptions,
|
||||
limit=limit,
|
||||
sorts=[['id', 'asc']],
|
||||
marker_obj=marker_obj)
|
||||
db_subscriptions = query.all()
|
||||
|
||||
return _make_subscription_list(context, cls(), db_subscriptions)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_filters(cls, context, read_deleted=None,
|
||||
filters=None, nextpage_opaque_marker=None):
|
||||
|
|
|
@ -29,6 +29,7 @@ from tacker.common import utils
|
|||
from tacker.db import api as db_api
|
||||
from tacker.db.db_sqlalchemy import api
|
||||
from tacker.db.db_sqlalchemy import models
|
||||
from tacker.db import sqlalchemyutils
|
||||
from tacker import objects
|
||||
from tacker.objects import base
|
||||
from tacker.objects import common
|
||||
|
@ -115,6 +116,39 @@ def _update_user_defined_data(context, package_uuid, user_data):
|
|||
return result
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_packages_get_by_filters_query(context, read_deleted=None,
|
||||
filters=None):
|
||||
|
||||
query = api.model_query(context, models.VnfPackage,
|
||||
read_deleted=read_deleted,
|
||||
project_only=True).options(joinedload('_metadata'))
|
||||
|
||||
if filters:
|
||||
# Need to join VnfDeploymentFlavour, VnfSoftwareImage and
|
||||
# VnfSoftwareImageMetadata db table explicitly
|
||||
# only when filters contains one of the column matching
|
||||
# from VnfSoftwareImage or VnfSoftwareImageMetadata db table.
|
||||
filter_data = json.dumps(filters)
|
||||
if 'VnfSoftwareImageMetadata' in filter_data:
|
||||
query = query.join(models.VnfDeploymentFlavour).join(
|
||||
models.VnfSoftwareImage).join(
|
||||
models.VnfSoftwareImageMetadata)
|
||||
elif 'VnfSoftwareImage' in filter_data:
|
||||
query = query.join(models.VnfDeploymentFlavour).join(
|
||||
models.VnfSoftwareImage)
|
||||
|
||||
if 'VnfPackageArtifactInfo' in filter_data:
|
||||
query = query.join(models.VnfPackageArtifactInfo)
|
||||
|
||||
if 'VnfPackageVnfd' in filter_data:
|
||||
query = query.join(models.VnfPackageVnfd)
|
||||
|
||||
query = common.apply_filters(query, filters)
|
||||
|
||||
return query
|
||||
|
||||
|
||||
@db_api.context_manager.reader
|
||||
def _vnf_package_get_by_id(context, package_uuid, columns_to_join=None):
|
||||
|
||||
|
@ -678,6 +712,22 @@ class VnfPackagesList(ovoo_base.ObjectListBase, base.TackerObject):
|
|||
return _make_vnf_packages_list(context, cls(), db_vnf_packages,
|
||||
expected_attrs)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_marker_filter(cls, context,
|
||||
limit, marker_obj,
|
||||
filters=None, read_deleted=None):
|
||||
query = _vnf_packages_get_by_filters_query(context,
|
||||
read_deleted=read_deleted,
|
||||
filters=filters)
|
||||
query = sqlalchemyutils.paginate_query(query,
|
||||
model=models.VnfPackage,
|
||||
limit=limit,
|
||||
sorts=[['id', 'asc']],
|
||||
marker_obj=marker_obj)
|
||||
db_vnf_packages = query.all()
|
||||
|
||||
return _make_vnf_packages_list(context, cls(), db_vnf_packages)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_filters(cls, context, read_deleted=None, filters=None):
|
||||
db_vnf_packages = _vnf_package_list_by_filters(context,
|
||||
|
|
|
@ -1882,7 +1882,15 @@ def _subscription_links(subscription_dict):
|
|||
return subscription_dict
|
||||
|
||||
|
||||
def return_subscription_obj(**updates):
|
||||
def return_lccn_subscription(**updates):
|
||||
subscription = _fake_subscription_obj(**updates)
|
||||
subscription['filter'] = json.dumps(subscription['filter'])
|
||||
obj = objects.LccnSubscription(**subscription)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
def return_lccn_subscription_obj(**updates):
|
||||
subscription = _fake_subscription_obj(**updates)
|
||||
subscription['filter'] = json.dumps(subscription['filter'])
|
||||
obj = objects.LccnSubscriptionRequest(**subscription)
|
||||
|
|
|
@ -1687,7 +1687,7 @@ class TestController(base.TestCase):
|
|||
|
||||
self.assertEqual(expected_message, exception.msg)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
def test_index(self, mock_vnf_list):
|
||||
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
||||
vnf_instance_1 = fakes.return_vnf_instance()
|
||||
|
@ -1701,7 +1701,8 @@ class TestController(base.TestCase):
|
|||
fields.VnfInstanceState.INSTANTIATED)]
|
||||
self.assertEqual(expected_result, resp.json)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter",
|
||||
return_value=[])
|
||||
def test_index_empty_response(self, mock_vnf_list):
|
||||
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
||||
mock_vnf_list.return_value = []
|
||||
|
@ -1831,7 +1832,7 @@ class TestController(base.TestCase):
|
|||
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
||||
resp.json['detail'])
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfInstanceName,'dummy_name')"},
|
||||
{'filter': "(in,vnfInstanceName,'dummy_name')"},
|
||||
|
@ -1863,7 +1864,7 @@ class TestController(base.TestCase):
|
|||
fields.VnfInstanceState.INSTANTIATED)]
|
||||
self.assertEqual(expected_result, res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
def test_index_filter_combination(self, mock_vnf_list):
|
||||
"""Test multiple filter parameters separated by semicolon."""
|
||||
params = {
|
||||
|
@ -1886,7 +1887,7 @@ class TestController(base.TestCase):
|
|||
fields.VnfInstanceState.INSTANTIATED)]
|
||||
self.assertEqual(expected_result, res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfInstanceName,dummy_value)"},
|
||||
{'filter': "(eq,vnfInstanceDescription,dummy value)"},
|
||||
|
@ -1921,7 +1922,7 @@ class TestController(base.TestCase):
|
|||
{'filter': "(eq,instantiatedInfo/additionalParams/error,'dummy')"},
|
||||
)
|
||||
def test_index_filter_attributes(self, filter_params,
|
||||
mock_vnf_list):
|
||||
mock_vnf_list):
|
||||
"""Test various attributes supported for filter parameter."""
|
||||
query = urllib.parse.urlencode(filter_params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
|
@ -1939,7 +1940,7 @@ class TestController(base.TestCase):
|
|||
fields.VnfInstanceState.INSTANTIATED)]
|
||||
self.assertEqual(expected_result, res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfInstanceName,value"},
|
||||
{'filter': "eq,vnfInstanceName,value)"},
|
||||
|
@ -1956,7 +1957,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfInstanceName,singl'quote)"},
|
||||
{'filter': "(eq,vnfInstanceName,three''' quotes)"},
|
||||
|
@ -1974,7 +1975,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,vnfdId,value1,value2)'},
|
||||
{'filter': '(fake,vnfdId,dummy_vnfd_id)'},
|
||||
|
@ -1989,7 +1990,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,fakeattr,fakevalue)'},
|
||||
{'filter': '(eq,,fakevalue)'},
|
||||
|
@ -2003,7 +2004,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,data/size,fake_value)'},
|
||||
{'filter': '(gt,data/createdAt,fake_value)'},
|
||||
|
@ -2019,47 +2020,85 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.vnf_instance.VnfInstanceList,
|
||||
"get_by_marker_filter")
|
||||
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
||||
@ddt.data(
|
||||
{'params': {'all_records': 'yes'},
|
||||
'result_names': ['sample1', 'sample2', 'sample3', 'sample4']},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['sample1', 'sample2', 'sample3', 'sample4']},
|
||||
{'params': {'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'44444444-4444-4444-4444-444444444444'},
|
||||
'result_names': []},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['sample3', 'sample4']},
|
||||
{'params': {},
|
||||
'result_names': ['sample2']}
|
||||
'result_names': ['sample1', 'sample2']}
|
||||
)
|
||||
def test_index_paging(self, values, mock_vnf_list):
|
||||
cfg.CONF.set_override('vnf_instance_num', 1, group='vnf_lcm')
|
||||
def test_index_paging(self, values,
|
||||
mock_marker_obj,
|
||||
mock_vnf_instance_list):
|
||||
ids = ['11111111-1111-1111-1111-111111111111',
|
||||
'22222222-2222-2222-2222-222222222222',
|
||||
'33333333-3333-3333-3333-333333333333',
|
||||
'44444444-4444-4444-4444-444444444444',
|
||||
None]
|
||||
cfg.CONF.set_override('vnf_instance_num', 2, group='vnf_lcm')
|
||||
query = urllib.parse.urlencode(values['params'])
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_instances?' + query)
|
||||
|
||||
mock_vnf_list.return_value = [
|
||||
fakes.return_vnf_instance(**{'vnf_instance_name': 'sample1'}),
|
||||
fakes.return_vnf_instance(**{'vnf_instance_name': 'sample2'}),
|
||||
fakes.return_vnf_instance(**{'vnf_instance_name': 'sample3'}),
|
||||
fakes.return_vnf_instance(**{'vnf_instance_name': 'sample4'})
|
||||
]
|
||||
target_index = []
|
||||
if 'all_records' in values['params'] \
|
||||
and values['params']['all_records'] == 'yes':
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1, 2, 3]
|
||||
elif 'nextpage_opaque_marker' in values['params']:
|
||||
mock_marker_obj.return_value = fakes.return_vnf_instance(
|
||||
**{'id': values['params']['nextpage_opaque_marker']})
|
||||
marker_obj_index = ids.index(mock_marker_obj.return_value['id'])
|
||||
for i in range(marker_obj_index + 1, len(ids) - 1):
|
||||
target_index.append(i)
|
||||
else:
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1]
|
||||
|
||||
mock_vnf_instance_list.return_value = []
|
||||
for index in range(len(target_index)):
|
||||
mock_vnf_instance_list.return_value.append(
|
||||
fakes.return_vnf_instance(**{'id': ids[target_index[index]],
|
||||
'vnf_instance_name':
|
||||
values['result_names'][index]}))
|
||||
|
||||
expected_result = []
|
||||
for name in values['result_names']:
|
||||
for index in range(len(target_index)):
|
||||
_links = fakes.fake_vnf_instance_response()['_links']
|
||||
expected_links = (re.sub("vnf_instances/[a-zA-Z0-9-]*",
|
||||
"vnf_instances/{}".format(ids[target_index[index]]),
|
||||
str(_links)))
|
||||
expected_links = json.loads(expected_links.replace("'", '"'))
|
||||
expected_result.append(fakes.fake_vnf_instance_response(
|
||||
**{'vnfInstanceName': name}))
|
||||
**{'vnfInstanceName': values['result_names'][index],
|
||||
'id': ids[target_index[index]],
|
||||
'_links': expected_links}))
|
||||
|
||||
expected_result_link = None
|
||||
if 'all_records' not in values['params'] and len(target_index) >= 2:
|
||||
expected_result_link = (
|
||||
'<http://localhost//vnflcm/v1/vnf_instances' +
|
||||
'?nextpage_opaque_marker=%s>; rel="next"'
|
||||
% ids[target_index[1]])
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
if 'Link' in res_dict.headers:
|
||||
next_url = re.findall('<(.*)>', res_dict.headers['Link'])[0]
|
||||
query = urllib.parse.urlparse(next_url).query
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_instances?' + query)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
self.assertEqual(expected_result, res_dict.json)
|
||||
if expected_result_link is not None:
|
||||
self.assertEqual(expected_result_link, res_dict.headers['Link'])
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'attribute_not_exist': 'some_value'},
|
||||
{'all_fields': {}},
|
||||
|
@ -2078,7 +2117,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'attribute_not_exist': 'some_value'},
|
||||
{'all_fields': {}},
|
||||
|
@ -3795,7 +3834,7 @@ class TestController(base.TestCase):
|
|||
resp = req.get_response(self.app)
|
||||
self.assertEqual(http_client.INTERNAL_SERVER_ERROR, resp.status_code)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
def test_op_occ_list(self, mock_op_occ_list):
|
||||
req = fake_request.HTTPRequest.blank('/vnflcm/v1/vnf_lcm_op_occs')
|
||||
|
||||
|
@ -3815,22 +3854,59 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
resp.json)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
@mock.patch.object(objects.vnf_lcm_op_occs.VnfLcmOpOccList,
|
||||
"get_by_marker_filter")
|
||||
@mock.patch.object(objects.vnf_lcm_op_occs.VnfLcmOpOcc, "get_by_id")
|
||||
@ddt.data(
|
||||
{'params': {'all_records': 'yes'},
|
||||
'result_names': ['INSTANTIATE', 'SCALE', 'HEAL', 'TERMINATE']},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['INSTANTIATE', 'SCALE', 'HEAL', 'TERMINATE']},
|
||||
{'params': {'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'44444444-4444-4444-4444-444444444444'},
|
||||
'result_names': []},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['HEAL', 'TERMINATE']},
|
||||
{'params': {},
|
||||
'result_names': ['SCALE']}
|
||||
'result_names': ['INSTANTIATE', 'SCALE']}
|
||||
)
|
||||
def test_op_occ_list_paging(self, values, mock_op_occ_list):
|
||||
cfg.CONF.set_override('lcm_op_occ_num', 1, group='vnf_lcm')
|
||||
def test_op_occ_list_paging(self, values,
|
||||
mock_marker_obj,
|
||||
mock_op_occ_list):
|
||||
ids = ['11111111-1111-1111-1111-111111111111',
|
||||
'22222222-2222-2222-2222-222222222222',
|
||||
'33333333-3333-3333-3333-333333333333',
|
||||
'44444444-4444-4444-4444-444444444444',
|
||||
None]
|
||||
cfg.CONF.set_override('lcm_op_occ_num', 2, group='vnf_lcm')
|
||||
query = urllib.parse.urlencode(values['params'])
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
target_index = []
|
||||
if 'all_records' in values['params'] \
|
||||
and values['params']['all_records'] == 'yes':
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1, 2, 3]
|
||||
elif 'nextpage_opaque_marker' in values['params']:
|
||||
mock_marker_obj.return_value = fakes.return_vnf_lcm_opoccs_obj(
|
||||
**{'id': values['params']['nextpage_opaque_marker']})
|
||||
if len(values['result_names']) > 0:
|
||||
target_index.append(
|
||||
ids.index(mock_marker_obj.return_value['id']) + 1)
|
||||
target_index.append(
|
||||
ids.index(mock_marker_obj.return_value['id']) + 2)
|
||||
else:
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1]
|
||||
|
||||
mock_op_occ_list.return_value = []
|
||||
for index in range(len(target_index)):
|
||||
mock_op_occ_list.return_value.append(
|
||||
fakes.return_vnf_lcm_opoccs_obj(
|
||||
**{'id': ids[target_index[index]],
|
||||
'operation': values['result_names'][index]}))
|
||||
|
||||
complex_attributes = [
|
||||
'error',
|
||||
|
@ -3838,34 +3914,36 @@ class TestController(base.TestCase):
|
|||
'operationParams',
|
||||
'changedInfo']
|
||||
|
||||
vnf_lcm_op_occ = [
|
||||
fakes.return_vnf_lcm_opoccs_obj(**{'operation': 'INSTANTIATE'}),
|
||||
fakes.return_vnf_lcm_opoccs_obj(**{'operation': 'SCALE'}),
|
||||
fakes.return_vnf_lcm_opoccs_obj(**{'operation': 'HEAL'}),
|
||||
fakes.return_vnf_lcm_opoccs_obj(**{'operation': 'TERMINATE'})
|
||||
]
|
||||
|
||||
expected_result = []
|
||||
for name in values['result_names']:
|
||||
for index in range(len(target_index)):
|
||||
_links = fakes.index_response()[0]['_links']
|
||||
expected_links = re.sub("vnf_lcm_op_occs/[a-zA-Z0-9-]*",
|
||||
"vnf_lcm_op_occs/{}".format(
|
||||
ids[target_index[index]]), str(_links))
|
||||
expected_links = json.loads(expected_links.replace("'", '"'))
|
||||
expected_result += fakes.index_response(
|
||||
remove_attrs=complex_attributes,
|
||||
vnf_lcm_op_occs_updates={'operation': name})
|
||||
vnf_lcm_op_occs_updates={'operation':
|
||||
values['result_names'][index],
|
||||
'id': ids[target_index[index]],
|
||||
'_links': expected_links})
|
||||
|
||||
expected_result_link = None
|
||||
if 'all_records' not in values['params'] and len(target_index) >= 2:
|
||||
expected_result_link = (
|
||||
'<http://localhost//vnflcm/v1/vnf_lcm_op_occs' +
|
||||
'?nextpage_opaque_marker=%s>; rel="next"'
|
||||
% ids[target_index[1]])
|
||||
|
||||
mock_op_occ_list.return_value = vnf_lcm_op_occ
|
||||
resp = self.controller.list_lcm_op_occs(req)
|
||||
|
||||
if 'Link' in resp.headers:
|
||||
next_url = re.findall('<(.*)>', resp.headers['Link'])[0]
|
||||
query = urllib.parse.urlparse(next_url).query
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
resp = self.controller.list_lcm_op_occs(req)
|
||||
|
||||
self.assertEqual(
|
||||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
resp.json)
|
||||
if expected_result_link is not None:
|
||||
self.assertEqual(expected_result_link, resp.headers['Link'])
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,id,f26f181d-7891-4720-b022-b074ec1733ef)'},
|
||||
{'filter': '(neq,operationState,COMPLETED)'},
|
||||
|
@ -3881,7 +3959,7 @@ class TestController(base.TestCase):
|
|||
"""(neq,operationParams,'"{"terminationType": "FORCEFUL"}"')"""},
|
||||
)
|
||||
def test_op_occ_filter_attributes(self, filter_params,
|
||||
mock_op_occ_list):
|
||||
mock_op_occ_list):
|
||||
query = urllib.parse.urlencode(filter_params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
|
@ -3902,8 +3980,9 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
def test_op_occ_filter_attributes_invalid_filter(self, mock_op_occ_list):
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
def test_op_occ_filter_attributes_invalid_filter(self,
|
||||
mock_op_occ_list):
|
||||
query = urllib.parse.urlencode({'filter': '(lt,non_existing,4)'})
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
|
@ -3913,8 +3992,9 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(
|
||||
exceptions.ValidationError, self.controller.list_lcm_op_occs, req)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
def test_op_occ_attribute_selector_all_fields(self, mock_op_occ_list):
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
def test_op_occ_attribute_selector_all_fields(self,
|
||||
mock_op_occ_list):
|
||||
params = {'all_fields': 'True'}
|
||||
query = urllib.parse.urlencode(params)
|
||||
req = fake_request.HTTPRequest.blank('/vnflcm/v1/vnf_lcm_op_occs?' +
|
||||
|
@ -3929,7 +4009,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'fields': 'error'},
|
||||
{'fields': 'resourceChanges'},
|
||||
|
@ -3937,7 +4017,7 @@ class TestController(base.TestCase):
|
|||
{'fields': 'changedInfo'}
|
||||
)
|
||||
def test_op_occ_attribute_selector_fields(self, filter_params,
|
||||
mock_op_occ_list):
|
||||
mock_op_occ_list):
|
||||
query = urllib.parse.urlencode(filter_params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
|
@ -3959,7 +4039,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'exclude_fields': 'error'},
|
||||
{'exclude_fields': 'resourceChanges'},
|
||||
|
@ -3967,7 +4047,7 @@ class TestController(base.TestCase):
|
|||
{'exclude_fields': 'changedInfo'}
|
||||
)
|
||||
def test_op_occ_attribute_selector_exclude_fields(self, filter_params,
|
||||
mock_op_occ_list):
|
||||
mock_op_occ_list):
|
||||
query = urllib.parse.urlencode(filter_params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
|
@ -3982,8 +4062,9 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result)),
|
||||
res_dict.json)
|
||||
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_filters")
|
||||
def test_op_occ_attribute_selector_fields_error(self, mock_op_occ_list):
|
||||
@mock.patch.object(objects.VnfLcmOpOccList, "get_by_marker_filter")
|
||||
def test_op_occ_attribute_selector_fields_error(self,
|
||||
mock_op_occ_list):
|
||||
query = urllib.parse.urlencode({'fields': 'non_existent_column'})
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_lcm_op_occs?' + query)
|
||||
|
@ -4409,7 +4490,7 @@ class TestController(base.TestCase):
|
|||
@mock.patch.object(vnf_subscription_view.ViewBuilder,
|
||||
"validate_filter")
|
||||
@mock.patch.object(objects.LccnSubscriptionList,
|
||||
"get_by_filters")
|
||||
"get_by_marker_filter")
|
||||
def test_subscription_list_all(self,
|
||||
mock_subscription_list,
|
||||
mock_subscription_filter,
|
||||
|
@ -4436,7 +4517,7 @@ class TestController(base.TestCase):
|
|||
@mock.patch.object(vnf_subscription_view.ViewBuilder,
|
||||
"validate_filter")
|
||||
@mock.patch.object(objects.LccnSubscriptionList,
|
||||
"get_by_filters")
|
||||
"get_by_marker_filter")
|
||||
def test_subscription_list_empty(self,
|
||||
mock_subscription_list,
|
||||
mock_subscription_filter,
|
||||
|
@ -4469,66 +4550,89 @@ class TestController(base.TestCase):
|
|||
resp = req.get_response(self.app)
|
||||
self.assertEqual(500, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
return_value={'VNFM':
|
||||
test_nfvo_plugin.FakeVNFMPlugin()})
|
||||
@mock.patch.object(vnf_subscription_view.ViewBuilder,
|
||||
"subscription_list")
|
||||
@mock.patch.object(vnf_subscription_view.ViewBuilder,
|
||||
"validate_filter")
|
||||
@mock.patch.object(objects.LccnSubscriptionList,
|
||||
"get_by_filters")
|
||||
@mock.patch.object(objects.vnf_lcm_subscriptions.LccnSubscriptionList,
|
||||
"get_by_marker_filter")
|
||||
@mock.patch.object(objects.LccnSubscription, "get_by_id")
|
||||
@ddt.data(
|
||||
{'params': {'all_records': 'yes'},
|
||||
'result_names': ['subscription_id_1', 'subscription_id_2',
|
||||
'subscription_id_3', 'subscription_id_4']},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['subscription_id_1', 'subscription_id_2',
|
||||
'subscription_id_3', 'subscription_id_4']},
|
||||
{'params': {'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'44444444-4444-4444-4444-444444444444'},
|
||||
'result_names': []},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['subscription_id_3', 'subscription_id_4']},
|
||||
{'params': {},
|
||||
'result_names': ['subscription_id_2']}
|
||||
'result_names': ['subscription_id_1', 'subscription_id_2']}
|
||||
)
|
||||
def test_subscription_list_paging(self,
|
||||
values,
|
||||
mock_subscription_list,
|
||||
mock_subscription_filter,
|
||||
mock_subscription_view,
|
||||
mock_get_service_plugins):
|
||||
mock_subscription_filter.return_value = None
|
||||
last = True
|
||||
cfg.CONF.set_override('subscription_num', 1, group='vnf_lcm')
|
||||
mock_marker_obj,
|
||||
mock_subscription_list):
|
||||
ids = ['11111111-1111-1111-1111-111111111111',
|
||||
'22222222-2222-2222-2222-222222222222',
|
||||
'33333333-3333-3333-3333-333333333333',
|
||||
'44444444-4444-4444-4444-444444444444',
|
||||
None]
|
||||
mock_marker_obj.return_value = None
|
||||
cfg.CONF.set_override('subscription_num', 2, group='vnf_lcm')
|
||||
query = urllib.parse.urlencode(values['params'])
|
||||
req = fake_request.HTTPRequest.blank('/subscriptions?' + query)
|
||||
req.method = 'GET'
|
||||
subscription_list = [
|
||||
fakes.return_subscription_object(
|
||||
**{'id': uuidsentinel.subscription_id_1}),
|
||||
fakes.return_subscription_object(
|
||||
**{'id': uuidsentinel.subscription_id_2}),
|
||||
fakes.return_subscription_object(
|
||||
**{'id': uuidsentinel.subscription_id_3}),
|
||||
fakes.return_subscription_object(
|
||||
**{'id': uuidsentinel.subscription_id_4})
|
||||
]
|
||||
mock_subscription_list.return_value = [subscription_list, last]
|
||||
mock_subscription_view.return_value = subscription_list
|
||||
|
||||
target_index = []
|
||||
if 'all_records' in values['params'] \
|
||||
and values['params']['all_records'] == 'yes':
|
||||
mock_marker_obj = None
|
||||
target_index = [0, 1, 2, 3]
|
||||
elif 'nextpage_opaque_marker' in values['params']:
|
||||
mock_marker_obj.return_value = fakes.return_subscription_object(
|
||||
**{'id': values['params']['nextpage_opaque_marker']})
|
||||
marker_obj_index = ids.index(mock_marker_obj.return_value['id'])
|
||||
for i in range(marker_obj_index + 1, len(ids) - 1):
|
||||
target_index.append(i)
|
||||
else:
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1]
|
||||
|
||||
mock_subscription_list.return_value = []
|
||||
|
||||
for index in range(len(target_index)):
|
||||
mock_subscription_list.return_value.append(
|
||||
fakes.return_lccn_subscription_obj(**{'id':
|
||||
ids[target_index[index]]}))
|
||||
|
||||
resp = self.controller.subscription_list(req)
|
||||
|
||||
if 'Link' in resp.headers:
|
||||
next_url = re.findall('<(.*)>', resp.headers['Link'])[0]
|
||||
query = urllib.parse.urlparse(next_url).query
|
||||
req = fake_request.HTTPRequest.blank('/subscriptions?' + query)
|
||||
resp = self.controller.subscription_list(req)
|
||||
|
||||
expected_result = []
|
||||
for name in values['result_names']:
|
||||
expected_result.append(fakes.return_subscription_object(
|
||||
**{'id': eval('uuidsentinel.' + name)}))
|
||||
for index in range(len(target_index)):
|
||||
href = ("http://localhost:9890//vnflcm/v1/subscriptions/{}"
|
||||
.format(ids[target_index[index]]))
|
||||
_link = {'self': {'href': href}}
|
||||
|
||||
subscription_object = fakes.return_subscription_object(
|
||||
**{'id': ids[target_index[index]], '_links': _link})
|
||||
|
||||
subscription_object['callbackUri'] = \
|
||||
subscription_object.pop('callback_uri')
|
||||
expected_result.append(subscription_object)
|
||||
|
||||
expected_result_link = None
|
||||
if 'all_records' not in values['params'] and len(target_index) >= 2:
|
||||
expected_result_link = (
|
||||
'<http://localhost//subscriptions' +
|
||||
'?nextpage_opaque_marker=%s>; rel="next"'
|
||||
% ids[target_index[1]])
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual(expected_result, resp.json)
|
||||
if expected_result_link is not None:
|
||||
self.assertEqual(expected_result_link, resp.headers['Link'])
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
return_value={'VNFM':
|
||||
|
@ -4538,7 +4642,7 @@ class TestController(base.TestCase):
|
|||
def test_subscription_show(self, mock_get_subscription,
|
||||
mock_get_service_plugins):
|
||||
mock_get_subscription.return_value =\
|
||||
fakes.return_subscription_obj()
|
||||
fakes.return_lccn_subscription_obj()
|
||||
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/subscriptions/%s' % uuidsentinel.subscription_id)
|
||||
|
@ -4559,7 +4663,7 @@ class TestController(base.TestCase):
|
|||
@mock.patch.object(vnf_subscription_view.ViewBuilder,
|
||||
"validate_filter")
|
||||
@mock.patch.object(objects.LccnSubscriptionList,
|
||||
"get_by_filters")
|
||||
"get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'operator': "eq", 'key': 'id',
|
||||
'value': uuidsentinel.subscription_id},
|
||||
|
|
|
@ -117,7 +117,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(exc.HTTPNotFound, self.controller.show,
|
||||
req, constants.UUID)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data('/vnfpkgm/v1/vnf_packages')
|
||||
def test_index(self, path, mock_vnf_list):
|
||||
req = fake_request.HTTPRequest.blank(path)
|
||||
|
@ -133,7 +133,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_attribute_selector_all_fields(self, mock_vnf_list):
|
||||
params = {'all_fields': ''}
|
||||
query = urllib.parse.urlencode(params)
|
||||
|
@ -146,7 +146,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_attribute_selector_exclude_default(self, mock_vnf_list):
|
||||
params = {'exclude_default': ''}
|
||||
query = urllib.parse.urlencode(params)
|
||||
|
@ -164,7 +164,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'exclude_fields': 'softwareImages'},
|
||||
{'exclude_fields': 'checksum'},
|
||||
|
@ -184,7 +184,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'fields': 'softwareImages'},
|
||||
{'fields': 'checksum'},
|
||||
|
@ -213,7 +213,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_attribute_selector_user_defined_data_combination(self,
|
||||
mock_vnf_list):
|
||||
"""Query user defined data with fields parameter
|
||||
|
@ -242,7 +242,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_attribute_selector_user_defined_data(self, mock_vnf_list):
|
||||
params = {'fields': 'userDefinedData/key1,userDefinedData/key2'}
|
||||
query = urllib.parse.urlencode(params)
|
||||
|
@ -256,7 +256,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_attribute_selector_nested_complex_attribute(self,
|
||||
mock_vnf_list):
|
||||
params = {'fields': 'softwareImages/checksum/algorithm,'
|
||||
|
@ -284,7 +284,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,vnfdId,%s)' % constants.UUID},
|
||||
{'filter': '(in,vnfdId,%s)' % constants.UUID},
|
||||
|
@ -325,7 +325,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
def test_index_filter_combination(self, mock_vnf_list):
|
||||
"""Test multiple filter parameters separated by semicolon """
|
||||
params = {'filter': '(eq,vnfdId,%s);(eq,id,%s)' %
|
||||
|
@ -345,7 +345,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,id,%s)' % constants.UUID},
|
||||
{'filter': '(eq,vnfdId,%s)' % constants.UUID},
|
||||
|
@ -394,7 +394,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfProductName,dummy_value)"},
|
||||
{'filter': "(eq,vnfProductName,dummy value)"},
|
||||
|
@ -428,7 +428,7 @@ class TestController(base.TestCase):
|
|||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfProductName,value"},
|
||||
{'filter': "eq,vnfProductName,value)"},
|
||||
|
@ -446,7 +446,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': "(eq,vnfProductName,singl'quote)"},
|
||||
{'filter': "(eq,vnfProductName,three''' quotes)"},
|
||||
|
@ -466,7 +466,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,vnfdId,value1,value2)'},
|
||||
{'filter': '(fake,vnfdId,dummy_vnfd_id)'},
|
||||
|
@ -481,7 +481,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,fakeattr,fakevalue)'},
|
||||
{'filter': '(eq,,fakevalue)'},
|
||||
|
@ -495,7 +495,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'filter': '(eq,id,fake_value)'},
|
||||
{'filter': '(eq,vnfd_id,fake_value)'},
|
||||
|
@ -515,7 +515,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'fields': 'nonExistentField'},
|
||||
{'exclude_fields': 'nonExistentField'}
|
||||
|
@ -529,7 +529,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'fields': 'softwareImages', 'all_fields': ''},
|
||||
{'exclude_fields': 'checksum', 'all_fields': ''},
|
||||
|
@ -545,7 +545,7 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@ddt.data(
|
||||
{'exclude_default': 'softwareImages'},
|
||||
{'all_fields': 'checksum'},
|
||||
|
@ -560,51 +560,92 @@ class TestController(base.TestCase):
|
|||
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
|
||||
req)
|
||||
|
||||
@mock.patch.object(VnfPackagesList, "get_by_filters")
|
||||
@mock.patch.object(VnfPackagesList, "get_by_marker_filter")
|
||||
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
||||
@ddt.data(
|
||||
{'params': {'all_records': 'yes'},
|
||||
'result_names': ['sample1', 'sample2', 'sample3', 'sample4']},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'all_records': 'yes', 'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['sample1', 'sample2', 'sample3', 'sample4']},
|
||||
{'params': {'nextpage_opaque_marker': 'abc'},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'44444444-4444-4444-4444-444444444444'},
|
||||
'result_names': []},
|
||||
{'params': {'nextpage_opaque_marker':
|
||||
'22222222-2222-2222-2222-222222222222'},
|
||||
'result_names': ['sample3', 'sample4']},
|
||||
{'params': {},
|
||||
'result_names': ['sample2']}
|
||||
'result_names': ['sample1', 'sample2']}
|
||||
)
|
||||
def test_index_paging(self, values, mock_vnf_list):
|
||||
cfg.CONF.set_override('vnf_package_num', 1, group='vnf_package')
|
||||
def test_index_paging(self, values,
|
||||
mock_marker_obj, mock_vnf_package_list):
|
||||
ids = ['11111111-1111-1111-1111-111111111111',
|
||||
'22222222-2222-2222-2222-222222222222',
|
||||
'33333333-3333-3333-3333-333333333333',
|
||||
'44444444-4444-4444-4444-444444444444',
|
||||
None]
|
||||
cfg.CONF.set_override('vnf_package_num', 2, group='vnf_package')
|
||||
query = urllib.parse.urlencode(values['params'])
|
||||
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
|
||||
query)
|
||||
mock_vnf_list.return_value = [
|
||||
fakes.return_vnfpkg_obj(
|
||||
vnfd_updates={'vnf_product_name': 'sample1'}),
|
||||
fakes.return_vnfpkg_obj(
|
||||
vnfd_updates={'vnf_product_name': 'sample2'}),
|
||||
fakes.return_vnfpkg_obj(
|
||||
vnfd_updates={'vnf_product_name': 'sample3'}),
|
||||
fakes.return_vnfpkg_obj(
|
||||
vnfd_updates={'vnf_product_name': 'sample4'})
|
||||
]
|
||||
|
||||
target_index = []
|
||||
if 'all_records' in values['params'] \
|
||||
and values['params']['all_records'] == 'yes':
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1, 2, 3]
|
||||
elif 'nextpage_opaque_marker' in values['params']:
|
||||
mock_marker_obj.return_value = fakes.return_vnfpkg_obj(
|
||||
vnf_package_updates={'id':
|
||||
values['params']['nextpage_opaque_marker']})
|
||||
marker_obj_index = ids.index(mock_marker_obj.return_value['id'])
|
||||
for i in range(marker_obj_index + 1, len(ids) - 1):
|
||||
target_index.append(i)
|
||||
else:
|
||||
mock_marker_obj.return_value = None
|
||||
target_index = [0, 1]
|
||||
|
||||
mock_vnf_package_list.return_value = []
|
||||
for index in range(len(target_index)):
|
||||
mock_vnf_package_list.return_value.append(
|
||||
fakes.return_vnfpkg_obj(
|
||||
vnf_package_updates={'id':
|
||||
ids[target_index[index]]},
|
||||
vnfd_updates={'vnf_product_name':
|
||||
values['result_names'][index]}))
|
||||
|
||||
expected_result = []
|
||||
for name in values['result_names']:
|
||||
expected_result += fakes.index_response(
|
||||
for index in range(len(target_index)):
|
||||
_links = fakes.index_response()[0]['_links']
|
||||
expected_links = (re.sub("vnf_packages/[a-zA-Z0-9-]*",
|
||||
"vnf_packages/{}".format(ids[target_index[index]]),
|
||||
str(_links)))
|
||||
expected_links = json.loads(expected_links.replace("'", '"'))
|
||||
print("expected_links", expected_links)
|
||||
|
||||
expected_result.append(fakes.index_response(
|
||||
remove_attrs=[
|
||||
'softwareImages',
|
||||
'checksum',
|
||||
'userDefinedData',
|
||||
'additionalArtifacts'],
|
||||
vnf_package_updates={'vnfProductName': name})
|
||||
vnf_package_updates={'vnfProductName':
|
||||
values['result_names'][index],
|
||||
'id': ids[target_index[index]],
|
||||
'_links': expected_links})[0])
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
if 'Link' in res_dict.headers:
|
||||
next_url = re.findall('<(.*)>', res_dict.headers['Link'])[0]
|
||||
query = urllib.parse.urlparse(next_url).query
|
||||
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
|
||||
query)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(
|
||||
jsonutils.loads(jsonutils.dump_as_bytes(expected_result,
|
||||
default=str)), res_dict.json)
|
||||
|
||||
expected_result_link = None
|
||||
if 'all_records' not in values['params'] and len(target_index) >= 2:
|
||||
expected_result_link = (
|
||||
'<http://localhost//vnfpkgm/v1/vnf_packages' +
|
||||
'?nextpage_opaque_marker=%s>; rel="next"'
|
||||
% ids[target_index[1]])
|
||||
|
||||
self.assertEqual(expected_result, res_dict.json)
|
||||
if expected_result_link is not None:
|
||||
self.assertEqual(expected_result_link, res_dict.headers['Link'])
|
||||
|
||||
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
|
||||
@mock.patch.object(VNFPackageRPCAPI, "delete_vnf_package")
|
||||
|
|
Loading…
Reference in New Issue