Merge "Add specifying tenant in notification"

This commit is contained in:
Zuul 2022-02-14 02:00:11 +00:00 committed by Gerrit Code Review
commit d3eb5e1559
13 changed files with 234 additions and 42 deletions

View File

@ -347,7 +347,8 @@ class VnfLcmController(wsgi.Controller):
operation=lcm_operation,
is_automatic_invocation=is_auto,
operation_params=operation_params,
error_point=error_point)
error_point=error_point,
tenant_id=context.tenant_id)
vnf_lcm_op_occs.create()
except Exception:
msg = _("Failed to create LCM occurrence")
@ -917,7 +918,8 @@ class VnfLcmController(wsgi.Controller):
'vnf_instance_id': id,
'id': op_occs_uuid,
'state_entered_time': timeutils.utcnow(),
'operationParams': str(body)}
'operationParams': str(body),
'tenant_id': request.context.project_id}
self.rpc_api.update(
context,
@ -950,6 +952,7 @@ class VnfLcmController(wsgi.Controller):
'callbackUri')
vnf_lcm_subscription.subscription_authentication = \
subscription_request_data.get('subscriptionAuthentication')
vnf_lcm_subscription.tenant_id = request.context.tenant_id
LOG.debug("filter %s " % subscription_request_data.get('filter'))
LOG.debug(
"filter type %s " %
@ -1228,7 +1231,8 @@ class VnfLcmController(wsgi.Controller):
is_automatic_invocation=scale_vnf_request.additional_params.get('\
is_auto'),
operation_params=json.dumps(operation_params),
error_point=1)
error_point=1,
tenant_id=vnf_instance.tenant_id)
vnf_lcm_op_occ.create()
else:
try:

View File

@ -1790,6 +1790,11 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
context,
notification_type=notification.get('notificationType')
)
vnf_lcm_subscriptions = \
self._extract_subscriptions(context, vnf_lcm_subscriptions,
notification.get('vnfInstanceId'))
if not vnf_lcm_subscriptions:
LOG.warning(
"vnf_lcm_subscription not found id[%s]" %
@ -1861,6 +1866,24 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
return -2
return 0
def _extract_subscriptions(self, context, vnf_lcm_subscriptions,
vnf_instance_id):
extract_vnf_lcm_subscriptions = []
try:
vnf_instance = objects.VnfInstance.get_by_id(
context, vnf_instance_id, read_deleted='yes')
except exceptions.VnfInstanceNotFound:
LOG.warning("Can not find vnf instance for notification: %s" % id)
return []
for subscription in vnf_lcm_subscriptions:
if subscription.tenant_id == vnf_instance.get("tenant_id"):
extract_vnf_lcm_subscriptions.append(subscription)
return extract_vnf_lcm_subscriptions
def _retry_check(self, retry_count):
time.sleep(CONF.vnf_lcm.retry_wait)
if retry_count == CONF.vnf_lcm.retry_num:
@ -2272,6 +2295,7 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
lcm_op_obj.is_automatic_invocation = 0
lcm_op_obj.is_cancel_pending = 0
lcm_op_obj.operation_params = vnf_lcm_opoccs.get('operationParams')
lcm_op_obj.tenant_id = vnf_lcm_opoccs.get('tenant_id')
try:
lcm_op_obj.create()

View File

@ -311,6 +311,7 @@ class VnfLcmSubscriptions(model_base.BASE, models.SoftDeleteMixin,
id = sa.Column(sa.String(36), nullable=False, primary_key=True)
callback_uri = sa.Column(sa.String(255), nullable=False)
subscription_authentication = sa.Column(sa.JSON, nullable=True)
tenant_id = sa.Column('tenant_id', sa.String(length=64), nullable=False)
subscription_filter = orm.relationship(
VnfLcmFilters,
@ -340,6 +341,7 @@ class VnfLcmOpOccs(model_base.BASE, models.SoftDeleteMixin,
changed_info = sa.Column(sa.JSON(), nullable=True)
changed_ext_connectivity = sa.Column(sa.JSON(), nullable=True)
error_point = sa.Column(sa.Integer, nullable=False)
tenant_id = sa.Column('tenant_id', sa.String(length=64), nullable=False)
class PlacementConstraint(model_base.BASE, models.SoftDeleteMixin,

View File

@ -1 +1 @@
3ff50553e9d3
d6ae359ab0d6

View File

@ -0,0 +1,39 @@
# Copyright 2022 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""add tenant_id to lcm_subscriptions and lcm_op_occs
Revision ID: d6ae359ab0d6
Revises: 3ff50553e9d3
Create Date: 2022-01-06 13:35:53.868106
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd6ae359ab0d6'
down_revision = '3ff50553e9d3'
def upgrade(active_plugins=None, options=None):
op.add_column('vnf_lcm_subscriptions',
sa.Column('tenant_id', sa.String(length=64),
nullable=False))
op.add_column('vnf_lcm_op_occs',
sa.Column('tenant_id', sa.String(length=64),
nullable=False))

View File

@ -41,10 +41,12 @@ LOG = logging.getLogger(__name__)
@db_api.context_manager.reader
def _vnf_instance_get_by_id(context, vnf_instance_id, columns_to_join=None):
def _vnf_instance_get_by_id(context, vnf_instance_id, columns_to_join=None,
read_deleted="no"):
query = api.model_query(context, models.VnfInstance,
read_deleted="no", project_only=True). \
read_deleted=read_deleted,
project_only=True). \
filter_by(id=vnf_instance_id)
if columns_to_join:
@ -517,10 +519,11 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
vnfd_id)
@base.remotable_classmethod
def get_by_id(cls, context, id):
def get_by_id(cls, context, id, read_deleted="no"):
expected_attrs = ["instantiated_vnf_info"]
db_vnf_instance = _vnf_instance_get_by_id(
context, id, columns_to_join=expected_attrs)
context, id, columns_to_join=expected_attrs,
read_deleted=read_deleted)
return cls._from_db_object(context, cls(), db_vnf_instance,
expected_attrs=expected_attrs)

View File

@ -49,6 +49,7 @@ def _vnf_lcm_op_occ_create(context, values):
'changed_info': values.changed_info,
'changed_ext_connectivity': values.changed_ext_connectivity,
'error_point': values.error_point,
'tenant_id': values.tenant_id,
}
if 'grant_id' in values:
fields['grant_id'] = values.grant_id
@ -242,7 +243,8 @@ class VnfLcmOpOcc(base.TackerObject, base.TackerObjectDictCompat,
'VnfInfoModifications', nullable=True, default=None),
'changed_ext_connectivity': fields.ListOfObjectsField(
'ExtVirtualLinkInfo', nullable=True, default=[]),
'error_point': fields.IntegerField(nullable=True, default=0)
'error_point': fields.IntegerField(nullable=True, default=0),
'tenant_id': fields.StringField(nullable=False)
}
ALL_ATTRIBUTES = {
@ -367,6 +369,7 @@ class VnfLcmOpOcc(base.TackerObject, base.TackerObjectDictCompat,
changed_info = data_dict.get('changed_info')
changed_ext_connectivity = data_dict.get('changed_ext_connectivity')
error_point = data_dict.get('error_point')
tenant_id = data_dict.get('tenant_id')
obj = cls(operation_state=operation_state,
state_entered_time=state_entered_time,
@ -381,7 +384,8 @@ class VnfLcmOpOcc(base.TackerObject, base.TackerObjectDictCompat,
resource_changes=resource_changes,
changed_info=changed_info,
changed_ext_connectivity=changed_ext_connectivity,
error_point=error_point
error_point=error_point,
tenant_id=tenant_id
)
return obj

View File

@ -109,7 +109,8 @@ def _vnf_lcm_subscriptions_get(context,
if notification_type == 'VnfLcmOperationOccurrenceNotification':
sql = (
"select"
" t1.id,t1.callback_uri,t1.subscription_authentication,t2.filter "
" t1.id,t1.callback_uri,t1.subscription_authentication,"
" t1.tenant_id, t2.filter "
" from "
" vnf_lcm_subscriptions t1, "
" (select distinct subscription_uuid,filter from vnf_lcm_filters "
@ -132,7 +133,8 @@ def _vnf_lcm_subscriptions_get(context,
else:
sql = (
"select"
" t1.id,t1.callback_uri,t1.subscription_authentication,t2.filter "
" t1.id,t1.callback_uri,t1.subscription_authentication,"
" t1.tenant_id, t2.filter "
" from "
" vnf_lcm_subscriptions t1, "
" (select distinct subscription_uuid,filter from vnf_lcm_filters "
@ -375,10 +377,12 @@ def _vnf_lcm_subscriptions_create(context, values, filter):
new_entries.append({"id": values.id,
"callback_uri": values.callback_uri,
"subscription_authentication":
values.subscription_authentication})
values.subscription_authentication,
"tenant_id": values.tenant_id})
else:
new_entries.append({"id": values.id,
"callback_uri": values.callback_uri})
"callback_uri": values.callback_uri,
"tenant_id": values.tenant_id})
context.session.execute(
models.VnfLcmSubscriptions.__table__.insert(None),
@ -480,7 +484,8 @@ class LccnSubscriptionRequest(base.TackerObject, base.TackerPersistentObject):
'callback_uri': fields.StringField(nullable=False),
'subscription_authentication':
fields.DictOfStringsField(nullable=True),
'filter': fields.StringField(nullable=True)
'filter': fields.StringField(nullable=True),
'tenant_id': fields.StringField(nullable=False)
}
@base.remotable
@ -578,6 +583,7 @@ class ChangeNotificationsFilter(
'operation_states': fields.StringField(nullable=True),
'operation_states_len': fields.IntegerField(
nullable=True, default=0),
'tenant_id': fields.StringField(nullable=False),
}
@ -631,6 +637,8 @@ class LccnSubscription(base.TackerObject, base.TackerPersistentObject):
'VnfLcmFilters'),
'callbackUri': ('callback_uri', 'string',
'VnfLcmSubscriptions'),
'tenantId': ('tenant_id', 'string',
'VnfLcmSubscriptions'),
}
FLATTEN_ATTRIBUTES = utils.flatten_dict(ALL_ATTRIBUTES.copy())

View File

@ -131,6 +131,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
auth_params).encode()
self.id = uuidsentinel.lcm_subscription_id
self.tenant_id = uuidsentinel.tenant_id
self.callback_uri = 'https://localhost/callback'.encode()
def __getattr__(self, name):
@ -158,7 +159,8 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'state_entered_time': datetime.datetime(
1900, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC),
'operationParams': 'operationParams'
'operationParams': 'operationParams',
'tenant_id': uuidsentinel.tenant_id
}
return vnf_lcm_opoccs
@ -2477,6 +2479,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
is_cancel_pending=False,
error_point=0,
id='00e1314d-2a82-40bd-b318-cc881243842d',
tenant_id='01db9967-ba45-4f1d-962d-7cbb825448f1',
created_at=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC))
vnf_lcm_op_occ.create()
@ -2625,6 +2628,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
operation_params='{"type": "SCALE_OUT", "aspect_id": "SP1"}',
is_cancel_pending=False,
error_point=0,
tenant_id='7cd42301-a3a5-47ad-a7bd-87b02540503b',
id='00e1314d-2a82-40bd-b318-cc881243843d',
created_at=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC))
@ -2728,6 +2732,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
operation_params='{"type": "SCALE_OUT", "aspect_id": "SP1"}',
error_point=0,
id='00e1314d-2a82-40bd-b318-cc881243843d',
tenant_id='00e1314d-2a82-40bd-b318-cc881243843r',
created_at=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC))
vnf_lcm_op_occ.create()
@ -2790,7 +2795,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_subscriptions_get):
mock_subscriptions_get.return_value = None
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfLcmOperationOccurrenceNotification'}
result = self.conductor.send_notification(self.context, notification)
@ -2798,19 +2803,23 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
self.assertEqual(result, -1)
mock_subscriptions_get.assert_called()
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_vnf_lcm_operation_occurrence(self,
mock_subscriptions_get):
mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri('POST',
"https://localhost/callback",
headers={
'Content-Type': 'application/json'},
status_code=204)
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
mock_subscriptions_get.return_value = self._create_subscriptions()
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfLcmOperationOccurrenceNotification',
'operationTypes': 'SCALE',
'operationStates': 'RESULT',
@ -2826,10 +2835,12 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
history, "https://localhost")
self.assertEqual(1, req_count)
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_vnf_identifier_creation(self,
mock_subscriptions_get):
mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
@ -2837,9 +2848,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'Content-Type': 'application/json'},
status_code=204)
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
mock_subscriptions_get.return_value = self._create_subscriptions()
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}
@ -2853,9 +2866,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
history, "https://localhost")
self.assertEqual(1, req_count)
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_with_auth_basic(self, mock_subscriptions_get):
def test_send_notification_with_auth_basic(self, mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri('POST',
"https://localhost/callback",
headers={
@ -2868,9 +2883,10 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
{'authType': 'BASIC',
'paramsBasic': {'userName': auth_user_name,
'password': auth_password}})
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}
@ -2888,10 +2904,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
auth_user_name,
auth_password)
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_with_auth_client_credentials(
self, mock_subscriptions_get):
self, mock_subscriptions_get, mock_vnf_by_id):
auth.auth_manager = auth._AuthManager()
self.requests_mock.register_uri(
'POST',
@ -2916,8 +2933,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
'clientPassword': auth_password,
'tokenEndpoint': token_endpoint}})
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}
@ -2933,19 +2953,23 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
self.assert_auth_basic(history[0], auth_user_name, auth_password)
self.assert_auth_client_credentials(history[1], "test_token")
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_retry_notification(self,
mock_subscriptions_get):
mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri('POST',
"https://localhost/callback",
headers={
'Content-Type': 'application/json'},
status_code=400)
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
mock_subscriptions_get.return_value = self._create_subscriptions()
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}
@ -2959,10 +2983,12 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
history, "https://localhost")
self.assertEqual(3, req_count)
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_send_error(self,
mock_subscriptions_get):
mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
@ -2970,10 +2996,11 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
mock_subscriptions_get.return_value = self._create_subscriptions()
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
result = self.conductor.send_notification(self.context, notification)
self.assertEqual(result, 0)
@ -2984,32 +3011,40 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
history, "https://localhost")
self.assertEqual(1, req_count)
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_internal_server_error(
self, mock_subscriptions_get):
self, mock_subscriptions_get,
mock_vnf_by_id):
mock_subscriptions_get.side_effect = Exception("MockException")
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationTypes': 'VnfIdentifierCreationNotification',
'links': {}}
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
result = self.conductor.send_notification(self.context, notification)
self.assertEqual(result, -2)
mock_subscriptions_get.assert_called()
@mock.patch.object(objects.VnfInstance, 'get_by_id')
@mock.patch.object(objects.LccnSubscriptionRequest,
'vnf_lcm_subscriptions_get')
def test_send_notification_timeout(self, mock_subscriptions_get):
def test_send_notification_timeout(self, mock_subscriptions_get,
mock_vnf_by_id):
self.requests_mock.register_uri(
'POST',
"https://localhost/callback",
exc=requests.Timeout)
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
fields.VnfInstanceState.INSTANTIATED)
mock_subscriptions_get.return_value = self._create_subscriptions()
notification = {
'vnfInstanceId': 'Test',
'vnfInstanceId': uuidsentinel.vnf_instance_id,
'notificationType': 'VnfIdentifierCreationNotification',
'links': {}}

View File

@ -59,7 +59,8 @@ class TestVnfLcm(SqlTestCase):
def test_vnf_instance_get_by_id(self):
result = vnf_instance._vnf_instance_get_by_id(
self.context, self.vnf_instance.id, columns_to_join=None)
self.context, self.vnf_instance.id,
columns_to_join=None, read_deleted="no")
self.assertEqual(self.vnf_instance.id, result.id)
def test_vnf_instance_create(self):

View File

@ -94,13 +94,15 @@ filter = {
}
],
"notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
"operationalState": ["ENABLED"]
"operationalState": ["ENABLED"],
"tenant_id": uuidsentinel.tenant_id
}
subscription_data = {
'id': "c3e5ea85-8e3d-42df-a636-3b7857cbd7f9",
'callback_uri': "fake_url",
'created_at': "2020-06-11 09:39:58"
'created_at': "2020-06-11 09:39:58",
'tenant_id': uuidsentinel.tenant_id
}
vnfd_data = {

View File

@ -76,6 +76,7 @@ class TestVnfLcmOpOcc(SqlTestCase):
context=self.context, **vnf_lcm_op_occs_data)
vnf_lcm_op_occs.create()
self.assertTrue(vnf_lcm_op_occs.vnf_instance_id)
self.assertTrue(vnf_lcm_op_occs.tenant_id)
def test_save(self):
id = uuidutils.generate_uuid()

View File

@ -104,7 +104,8 @@ class TestVnfLcmSubScriptions(SqlTestCase):
/530a3c43-043a-4b84-9d65-aa0df49f7ced"\
}\
},\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced"\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced",\
"tenant_id": "8cd59fef-397e-4bec-8621-0e69225434f0"\
}'
subscription_obj = \
@ -195,7 +196,8 @@ class TestVnfLcmSubScriptions(SqlTestCase):
/530a3c43-043a-4b84-9d65-aa0df49f7ced"\
}\
},\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced"\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced",\
"tenant_id": "8cd59fef-397e-4bec-8621-0e69225434f0"\
}'
result = subscription_obj.vnf_lcm_subscriptions_show(
@ -258,7 +260,8 @@ class TestVnfLcmSubScriptions(SqlTestCase):
/530a3c43-043a-4b84-9d65-aa0df49f7ced"\
}\
},\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced"\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced",\
"tenant_id": "8cd59fef-397e-4bec-8621-0e69225434f0"\
}'
result = subscription_obj.vnf_lcm_subscriptions_list(self.context)
@ -273,3 +276,69 @@ class TestVnfLcmSubScriptions(SqlTestCase):
self.subscription.destroy(self.context, self.subscription.id)
mock_vnf_lcm_subscriptions_destroy.assert_called_with(
self.context, self.subscription.id)
@mock.patch.object(objects.vnf_lcm_subscriptions,
'_vnf_lcm_subscriptions_get')
def test_get(self, mock_vnf_lcm_subscriptions_get):
subscription_obj = \
objects.vnf_lcm_subscriptions.LccnSubscriptionRequest(
context=self.context)
mock_vnf_lcm_subscriptions_get.return_value = \
'{\
"filter": "{"operationStates": ["COMPLETED"],\
"vnfInstanceNames": ["xxxxxxxxxxxxxxxxxx"],\
"operationTypes": ["INSTANTIATE"],\
"vnfdIds": ["405d73c7-e964-4c8b-a914-41478ccd7c42"],\
"vnfProductsFromProviders": [{\
"vnfProvider": "x2x", \
"vnfProducts": [{\
"vnfProductName": "x2xx", \
"versions": [{\
"vnfSoftwareVersion": "xx2XX", \
"vnfdVersions": ["ss2"]\
}]\
}]\
}, \
{\
"vnfProvider": "z2z",\
"vnfProducts": [{\
"vnfProductName": "z2zx", \
"versions": [{\
"vnfSoftwareVersion": "xx3XX",\
"vnfdVersions": \
["s3sx", "s3sa"]\
}\
]},\
{\
"vnfProductName": "zz3ex",\
"versions": [{\
"vnfSoftwareVersion": "xxe3eXz",\
"vnfdVersions": ["ss3xz", "s3esaz"]\
},\
{\
"vnfSoftwareVersion": "xxeeeXw", \
"vnfdVersions": ["ss3xw", "ss3w"]\
}]\
}]\
}],\
"notificationTypes": [\
"VnfLcmOperationOccurrenceNotification"],\
"vnfInstanceIds": ["fb0b9a12-4b55-47ac-9ca8-5fdd52c4c07f"]}",\
"callbackUri": "http://localhost/xxx",\
"_links": {\
"self": {\
"href":\
"http://localhost:9890//vnflcm/v1/subscriptions\
/530a3c43-043a-4b84-9d65-aa0df49f7ced"\
}\
},\
"id": "530a3c43-043a-4b84-9d65-aa0df49f7ced",\
"tenant_id": "8cd59fef-397e-4bec-8621-0e69225434f0"\
}'
result = subscription_obj.vnf_lcm_subscriptions_get(self.context,
'VnfLcmOperationOccurrenceNotification')
self.assertIn("tenant_id", result)
result = subscription_obj.vnf_lcm_subscriptions_get(self.context,
None)
self.assertIn("tenant_id", result)