Addition of location header field in response
For below VNFInstance's operations "Location header" will be present 1) heal 2) instantiate 3) terminate Response header will contain the "Location" HTTP header field. And this "Location" HTTP header will contain "vnfLcmOpOccId". This patch changes notification parameter based on SOL013 7.1.4 Type: NotificationLink. As per SOL003, 5.5.2.17, VnfLcmOperationOccurrenceNotification represents a VNF lifecycle management operation occurrence notification, which informs the receiver of changes in the VNF lifecycle caused by a VNF LCM operation occurrence. This notification shall be triggered by the VNFM, when there is a change in the state of a VNF LCM operation occurrence that changes the VNF lifecycle, including: • Instantiation of the VNF • Scaling of the VNF instance (including auto-scaling) • Healing of the VNF and others. URI of a resource referenced from a notification should be an absolute URI if APIRoot is known. Co-Authored-By: Sheel Rana <ranasheel2000@gmail.com> Closes-Bug: #1915107 Closes-Bug: #1911625 Change-Id: I3a325634f88b9521d7fa2f524076934df315742d
This commit is contained in:
parent
6fc64560e2
commit
5a9ae0c858
|
@ -193,10 +193,12 @@ class VnfLcmController(wsgi.Controller):
|
|||
self._view_builder_subscription = vnf_subscription_view.ViewBuilder()
|
||||
|
||||
def _get_vnf_instance_href(self, vnf_instance):
|
||||
return '/vnflcm/v1/vnf_instances/%s' % vnf_instance.id
|
||||
return '{}vnflcm/v1/vnf_instances/{}'.format(
|
||||
CONF.vnf_lcm.endpoint_url, vnf_instance.id)
|
||||
|
||||
def _get_vnf_lcm_op_occs_href(self, vnf_lcm_op_occs_id):
|
||||
return '/vnflcm/v1/vnf_lcm_op_occs/%s' % vnf_lcm_op_occs_id
|
||||
return '{}vnflcm/v1/vnf_lcm_op_occs/{}'.format(
|
||||
CONF.vnf_lcm.endpoint_url, vnf_lcm_op_occs_id)
|
||||
|
||||
def _get_vnf_instance(self, context, id):
|
||||
# check if id is of type uuid format
|
||||
|
@ -643,6 +645,13 @@ class VnfLcmController(wsgi.Controller):
|
|||
self.rpc_api.instantiate(context, vnf_instance, vnf,
|
||||
instantiate_vnf_request,
|
||||
vnf_lcm_op_occs_id)
|
||||
# set response header
|
||||
res = webob.Response()
|
||||
res.status_int = 202
|
||||
location = ('Location',
|
||||
self._get_vnf_lcm_op_occs_href(vnf_lcm_op_occs_id))
|
||||
res.headerlist.append(location)
|
||||
return res
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
@wsgi.expected_errors((http_client.FORBIDDEN, http_client.NOT_FOUND,
|
||||
|
@ -655,7 +664,7 @@ class VnfLcmController(wsgi.Controller):
|
|||
vnf = self._get_vnf(context, id)
|
||||
vnf_instance = self._get_vnf_instance(context, id)
|
||||
|
||||
self._instantiate(context, vnf_instance, vnf, body)
|
||||
return self._instantiate(context, vnf_instance, vnf, body)
|
||||
|
||||
@check_vnf_state(action="terminate",
|
||||
instantiation_state=[
|
||||
|
@ -685,6 +694,13 @@ class VnfLcmController(wsgi.Controller):
|
|||
if vnf_lcm_op_occs_id:
|
||||
self.rpc_api.terminate(context, vnf_instance, vnf,
|
||||
terminate_vnf_req, vnf_lcm_op_occs_id)
|
||||
# set response header
|
||||
res = webob.Response()
|
||||
res.status_int = 202
|
||||
location = ('Location',
|
||||
self._get_vnf_lcm_op_occs_href(vnf_lcm_op_occs_id))
|
||||
res.headerlist.append(location)
|
||||
return res
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
@wsgi.expected_errors((http_client.BAD_REQUEST, http_client.FORBIDDEN,
|
||||
|
@ -696,7 +712,7 @@ class VnfLcmController(wsgi.Controller):
|
|||
|
||||
vnf = self._get_vnf(context, id)
|
||||
vnf_instance = self._get_vnf_instance(context, id)
|
||||
self._terminate(context, vnf_instance, vnf, body)
|
||||
return self._terminate(context, vnf_instance, vnf, body)
|
||||
|
||||
@check_vnf_status_and_error_point(action="heal",
|
||||
status=[constants.ACTIVE])
|
||||
|
@ -733,6 +749,14 @@ class VnfLcmController(wsgi.Controller):
|
|||
self.rpc_api.heal(context, vnf_instance, vnf_dict,
|
||||
heal_vnf_request, vnf_lcm_op_occs_id)
|
||||
|
||||
# set response header
|
||||
res = webob.Response()
|
||||
res.status_int = 202
|
||||
location = ('Location',
|
||||
self._get_vnf_lcm_op_occs_href(vnf_lcm_op_occs_id))
|
||||
res.headerlist.append(location)
|
||||
return res
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
@wsgi.expected_errors((http_client.BAD_REQUEST, http_client.FORBIDDEN,
|
||||
http_client.NOT_FOUND, http_client.CONFLICT))
|
||||
|
@ -758,7 +782,7 @@ class VnfLcmController(wsgi.Controller):
|
|||
state=vnf_instance.task_state,
|
||||
action='heal')
|
||||
|
||||
self._heal(context, vnf_instance, vnf, body)
|
||||
return self._heal(context, vnf_instance, vnf, body)
|
||||
|
||||
@wsgi.response(http_client.OK)
|
||||
@wsgi.expected_errors((http_client.FORBIDDEN, http_client.NOT_FOUND))
|
||||
|
|
|
@ -182,6 +182,8 @@ class FakeVNFMPlugin(mock.Mock):
|
|||
|
||||
@ddt.ddt
|
||||
class TestController(base.TestCase):
|
||||
expected_location_prefix = ('http://localhost:9890/'
|
||||
'vnflcm/v1/vnf_lcm_op_occs/')
|
||||
|
||||
def setUp(self):
|
||||
super(TestController, self).setUp()
|
||||
|
@ -298,7 +300,7 @@ class TestController(base.TestCase):
|
|||
updates = {"vnfInstanceName": "SampleVnf",
|
||||
"vnfInstanceDescription": "SampleVnf Description"}
|
||||
expected_vnf = fakes.fake_vnf_instance_response(**updates)
|
||||
location_header = ('http://localhost/vnflcm/v1/vnf_instances/%s'
|
||||
location_header = ('http://localhost:9890/vnflcm/v1/vnf_instances/%s'
|
||||
% resp.json['id'])
|
||||
|
||||
self.assertEqual(expected_vnf, resp.json)
|
||||
|
@ -599,6 +601,10 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertTrue('Location' in resp.headers.keys())
|
||||
expected_location = (self.expected_location_prefix +
|
||||
str(mock_insta_notfi_process.return_value))
|
||||
self.assertEqual(expected_location, resp.headers['location'])
|
||||
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
||||
mock_instantiate.assert_called_once()
|
||||
|
||||
|
@ -636,6 +642,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("No flavour with id 'invalid'.",
|
||||
resp.json['badRequest']['message'])
|
||||
|
@ -682,6 +689,10 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertTrue('Location' in resp.headers.keys())
|
||||
expected_location = (self.expected_location_prefix +
|
||||
str(mock_insta_notif_process.return_value))
|
||||
self.assertEqual(expected_location, resp.headers['location'])
|
||||
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
||||
mock_instantiate.assert_called_once()
|
||||
mock_get_vnf.assert_called_once()
|
||||
|
@ -728,6 +739,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("No instantiation level with id "
|
||||
"'instantiation_level_1'.",
|
||||
|
@ -770,6 +782,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("No instantiation level with id 'non-existing'.",
|
||||
resp.json['badRequest']['message'])
|
||||
|
@ -821,6 +834,10 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertTrue('Location' in resp.headers.keys())
|
||||
expected_location = (self.expected_location_prefix +
|
||||
str(mock_insta_notif_process.return_value))
|
||||
self.assertEqual(expected_location, resp.headers['location'])
|
||||
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
||||
mock_instantiate.assert_called_once()
|
||||
mock_get_vnf.assert_called_once()
|
||||
|
@ -867,6 +884,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("VimConnection id is not found: %s" %
|
||||
uuidsentinel.vim_id,
|
||||
|
@ -915,6 +933,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("Region not found for the VimConnection: %s" %
|
||||
uuidsentinel.vim_id,
|
||||
|
@ -957,6 +976,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("Default VIM is not defined.",
|
||||
resp.json['badRequest']['message'])
|
||||
|
@ -983,6 +1003,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
@ -1008,7 +1029,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
||||
expected_msg = ("Vnf instance %s in task_state INSTANTIATING. Cannot "
|
||||
"instantiate while the vnf instance is in this state.")
|
||||
|
@ -1069,7 +1090,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("'flavourId' is a required property",
|
||||
resp.json['badRequest']['message'])
|
||||
|
@ -1093,7 +1114,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.INTERNAL_SERVER_ERROR, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
@ -1110,7 +1131,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
||||
self.assertEqual(
|
||||
"Can not find requested vnf: %s" % constants.INVALID_UUID,
|
||||
|
@ -1135,7 +1156,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call Instantiate API
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
||||
self.assertEqual("Can not find requested vnf instance: %s" %
|
||||
uuidsentinel.vnf_instance_id,
|
||||
|
@ -1156,6 +1177,7 @@ class TestController(base.TestCase):
|
|||
req.headers['Content-Type'] = 'application/json'
|
||||
req.method = method
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
@ -1261,6 +1283,9 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
expected_location = (self.expected_location_prefix +
|
||||
str(mock_notification_process.return_value))
|
||||
self.assertEqual(expected_location, resp.headers['location'])
|
||||
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
||||
mock_terminate.assert_called_once()
|
||||
mock_get_vnf.assert_called_once()
|
||||
|
@ -1317,6 +1342,7 @@ class TestController(base.TestCase):
|
|||
|
||||
# Call terminate API
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
self.assertEqual("'terminationType' is a required property",
|
||||
resp.json['badRequest']['message'])
|
||||
|
@ -1336,6 +1362,7 @@ class TestController(base.TestCase):
|
|||
req.headers['Content-Type'] = 'application/json'
|
||||
req.method = method
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
@ -1356,7 +1383,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
||||
self.assertEqual("Can not find requested vnf instance: %s" %
|
||||
uuidsentinel.vnf_instance_id,
|
||||
|
@ -1387,7 +1414,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
||||
expected_msg = ("Vnf instance %s in task_state TERMINATING. Cannot "
|
||||
"terminate while the vnf instance is in this state.")
|
||||
|
@ -1423,7 +1450,10 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertTrue('Location' in resp.headers.keys())
|
||||
expected_location = (self.expected_location_prefix +
|
||||
str(mock_heal_notif_process.return_value))
|
||||
self.assertEqual(expected_location, resp.headers['location'])
|
||||
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
||||
mock_rpc_heal.assert_called_once()
|
||||
|
||||
|
@ -1440,6 +1470,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
@ -1468,6 +1499,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
||||
expected_msg = ("Vnf instance %s in instantiation_state "
|
||||
"NOT_INSTANTIATED. Cannot heal while the vnf instance "
|
||||
|
@ -1498,6 +1530,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
||||
expected_msg = ("Vnf instance %s in task_state "
|
||||
"HEALING. Cannot heal while the vnf instance "
|
||||
|
@ -1533,6 +1566,7 @@ class TestController(base.TestCase):
|
|||
req.method = 'POST'
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
||||
expected_msg = "Vnfc id %s not present in vnf instance %s"
|
||||
self.assertEqual(expected_msg % (uuidsentinel.vnfc_instance_id,
|
||||
|
@ -1553,7 +1587,7 @@ class TestController(base.TestCase):
|
|||
req.method = method
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
|
||||
self.assertFalse('Location' in resp.headers.keys())
|
||||
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
|
|
Loading…
Reference in New Issue