diff --git a/api-ref/source/v1/parameters_vnflcm.yaml b/api-ref/source/v1/parameters_vnflcm.yaml index 55eba26dc..726f23c60 100644 --- a/api-ref/source/v1/parameters_vnflcm.yaml +++ b/api-ref/source/v1/parameters_vnflcm.yaml @@ -655,6 +655,13 @@ filter_operation_types: in: body required: false type: string +filter_vnf_instance_subscription_filter: + description: | + This type represents subscription filter + criteria to match VNF instances. + in: body + required: false + type: object fixed_addresses: description: | Fixed addresses to assign (from the subnet defined by "subnetId" diff --git a/api-ref/source/v1/samples/vnflcm/show-subscription-response.json b/api-ref/source/v1/samples/vnflcm/show-subscription-response.json index b8e6df5b8..34f99628a 100644 --- a/api-ref/source/v1/samples/vnflcm/show-subscription-response.json +++ b/api-ref/source/v1/samples/vnflcm/show-subscription-response.json @@ -1,14 +1,52 @@ -{ - "id": "76057f8e65ab37fb82d9382dfc3f3c8b", - "filter": { - "notificationTypes": [ - "VnfLcmOperationOccurrenceNotification" - ] - }, - "callbackUri": "http://sample1.com/notification", - "_links": { - "self": { - "href": "https://sample1.com/vnflcm/v1/subscriptions/76057f8e65ab37fb82d9382dfc3f3c8b" - } - } +{ + "id": "76057f8e65ab37fb82d9382dfc3f3c8b", + "filter": { + "vnfInstanceSubscriptionFilter": { + "vnfdIds": [], + "vnfProductsFromProviders": { + "vnfProvider": "Vnf Provider 1", + "vnfProducts": [ + { + "vnfProductName": "Vnf Product 1", + "versions": [ + { + "vnfSoftwareVersion": "v1", + "vnfdVersions": [ + "vnfd.v1.1" + ] + } + ] + } + ] + } + }, + "notificationTypes": [ + "VnfLcmOperationOccurrenceNotification", + "VnfIdentifierCreationNotification", + "VnfIdentifierDeletionNotification" + ], + "operationTypes": [ + "INSTANTIATE", + "SCALE", + "TERMINATE", + "HEAL", + "CHANGE_EXT_CONN", + "MODIFY_INFO" + ], + "operationStates": [ + "STARTING", + "PROCESSING", + "COMPLETED", + "FAILED_TEMP", + "FAILED", + "ROLLING_BACK", + "ROLLED_BACK" + ] + }, + "callbackUri": "http://sample1.com/notification", + "_links": { + "self": { + "href": "https://sample1.com/vnflcm/v1/subscriptions/76057f8e65ab37fb82d9382dfc3f3c8b" + } + } } \ No newline at end of file diff --git a/api-ref/source/v1/vnflcm.inc b/api-ref/source/v1/vnflcm.inc index 64017edc7..d233ea1c6 100644 --- a/api-ref/source/v1/vnflcm.inc +++ b/api-ref/source/v1/vnflcm.inc @@ -1258,8 +1258,10 @@ Response Parameters - id: subscription_id_response - filter: filter + - vnfInstanceSubscriptionFilter: filter_vnf_instance_subscription_filter - notificationTypes: filter_notification_types - operationTypes: filter_operation_types + - operationStates: filter_operation_states - callbackUri: callback_uri - _links: vnf_instance_links diff --git a/tacker/api/views/vnf_lcm.py b/tacker/api/views/vnf_lcm.py index c951a205e..8f1fb0fae 100644 --- a/tacker/api/views/vnf_lcm.py +++ b/tacker/api/views/vnf_lcm.py @@ -282,6 +282,9 @@ class ViewBuilder(base.BaseViewBuilder): return self._subscription_filter( vnf_lcm_subscriptions, nextpage_opaque_marker, paging) + # TODO(esto.aln): To remove show subscription related processing + # in vnf_lcm.py. Current processing for show subscription is in + # vnf_subscriptions.py. def subscription_show(self, vnf_lcm_subscriptions): return self._get_vnf_lcm_subscription(vnf_lcm_subscriptions) diff --git a/tacker/tests/unit/vnflcm/fakes.py b/tacker/tests/unit/vnflcm/fakes.py index 9a452020f..4c9015e78 100644 --- a/tacker/tests/unit/vnflcm/fakes.py +++ b/tacker/tests/unit/vnflcm/fakes.py @@ -16,6 +16,7 @@ from copy import deepcopy import datetime import iso8601 +import json import os import webob @@ -1692,10 +1693,27 @@ def _fake_subscription_obj(**updates): "vnfInstanceNames": ["Vnf Name 1"] }, "notificationTypes": [ - "VnfLcmOperationOccurrenceNotification" + "VnfLcmOperationOccurrenceNotification", + "VnfIdentifierCreationNotification", + "VnfIdentifierDeletionNotification" ], - "operationTypes": ["INSTANTIATE"], - "operationStates": ["STARTING"] + "operationTypes": [ + "INSTANTIATE", + "SCALE", + "TERMINATE", + "HEAL", + "CHANGE_EXT_CONN", + "MODIFY_INFO" + ], + "operationStates": [ + "STARTING", + "PROCESSING", + "COMPLETED", + "FAILED_TEMP", + "FAILED", + "ROLLING_BACK", + "ROLLED_BACK" + ] }, 'callback_uri': 'http://localhost/sample_callback_uri'} @@ -1713,3 +1731,34 @@ def return_subscription_object(**updates): def return_vnf_subscription_list(**updates): vnc_lcm_subscription = return_subscription_object(**updates) return [vnc_lcm_subscription] + + +def _subscription_links(subscription_dict): + links = { + "_links": { + "self": { + "href": "%(endpoint)s/vnflcm/v1/subscriptions/%(id)s" + % {'id': subscription_dict['id'], + 'endpoint': CONF.vnf_lcm.endpoint_url} + } + } + } + subscription_dict.update(links) + + return subscription_dict + + +def return_subscription_obj(**updates): + subscription = _fake_subscription_obj(**updates) + subscription['filter'] = json.dumps(subscription['filter']) + obj = objects.LccnSubscriptionRequest(**subscription) + + return obj + + +def fake_subscription_response(**updates): + data = _fake_subscription_obj(**updates) + data = utils.convert_snakecase_to_camelcase(data) + data = _subscription_links(data) + + return data diff --git a/tacker/tests/unit/vnflcm/test_controller.py b/tacker/tests/unit/vnflcm/test_controller.py index 9950dcb18..99f06ec02 100644 --- a/tacker/tests/unit/vnflcm/test_controller.py +++ b/tacker/tests/unit/vnflcm/test_controller.py @@ -3943,6 +3943,27 @@ 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(objects.LccnSubscriptionRequest, + "vnf_lcm_subscriptions_show") + def test_subscription_show(self, mock_get_subscription, + mock_get_service_plugins): + mock_get_subscription.return_value =\ + fakes.return_subscription_obj() + + req = fake_request.HTTPRequest.blank( + '/subscriptions/%s' % uuidsentinel.subscription_id) + req.method = 'GET' + + resp = req.get_response(self.app) + + expected_vnf = fakes.fake_subscription_response() + + self.assertEqual(http_client.OK, resp.status_code) + self.assertEqual(expected_vnf, resp.json) + @mock.patch.object(TackerManager, 'get_service_plugins', return_value={'VNFM': test_nfvo_plugin.FakeVNFMPlugin()}) @@ -3999,6 +4020,26 @@ class TestController(base.TestCase): else: self.assertEqual(expected_result, resp.json) + @mock.patch.object(TackerManager, 'get_service_plugins', + return_value={'VNFM': + test_nfvo_plugin.FakeVNFMPlugin()}) + @mock.patch.object(objects.LccnSubscriptionRequest, + "vnf_lcm_subscriptions_show") + def test_subscription_show_not_found(self, mock_get_subscription, + mock_get_service_plugins): + req = fake_request.HTTPRequest.blank( + '/subscriptions/%s' % uuidsentinel.subscription_id) + req.method = 'GET' + + mock_get_subscription.return_value = None + + msg = _("Can not find requested vnf lcm subscriptions: %s" + % uuidsentinel.subscription_id) + res = self._make_problem_detail(msg, 404, title='Not Found') + + resp = req.get_response(self.app) + self.assertEqual(res.text, resp.text) + @mock.patch.object(TackerManager, 'get_service_plugins', return_value={'VNFM': test_nfvo_plugin.FakeVNFMPlugin()}) @@ -4011,3 +4052,19 @@ class TestController(base.TestCase): resp = req.get_response(self.app) self.assertEqual(400, resp.status_code) + + @mock.patch.object(TackerManager, 'get_service_plugins', + return_value={'VNFM': + test_nfvo_plugin.FakeVNFMPlugin()}) + @mock.patch.object(objects.LccnSubscriptionRequest, + "vnf_lcm_subscriptions_show") + def test_subscription_show_error(self, mock_get_subscription, + mock_get_service_plugins): + req = fake_request.HTTPRequest.blank( + '/subscriptions/%s' % uuidsentinel.subscription_id) + req.method = 'GET' + + mock_get_subscription.side_effect = Exception + + resp = req.get_response(self.app) + self.assertEqual(500, resp.status_code)