Handled exception in exception of instantiation
When exception occurs in exception block of instantiation, heal, termination, change external connectivity operations then notification was not sent. Implemented exception handling in exception block of instantiation, heal, termination, change external connectivity operations. Closes-Bug: #1983096 Change-Id: I645e342167d22ac3764cdb20ef1a0f77f801fb95
This commit is contained in:
parent
bff12b4cfb
commit
3bdb71c812
@ -1744,7 +1744,11 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
|
||||
or operation_state == \
|
||||
fields.LcmOccsOperationState.FAILED:
|
||||
notification_data['error'] = error
|
||||
except Exception as ex:
|
||||
LOG.error("Error in getting resources for op id - {}.\
|
||||
Details: {}".format(vnf_lcm_op_occs_id, str(ex)))
|
||||
|
||||
try:
|
||||
# send notification
|
||||
self.send_notification(context, notification_data)
|
||||
except Exception as ex:
|
||||
@ -2000,29 +2004,33 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
|
||||
operation_state=fields.LcmOccsOperationState.COMPLETED)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.warning(traceback.format_exc())
|
||||
LOG.warning("Exception occured in instantiation for vnf "
|
||||
"instance %(id)s. Error: %(error)s",
|
||||
{"id": vnf_instance.id, "error": ex})
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
try:
|
||||
LOG.warning(traceback.format_exc())
|
||||
LOG.warning("Exception occured in instantiation for vnf "
|
||||
"instance %(id)s. Error: %(error)s",
|
||||
{"id": vnf_instance.id, "error": ex})
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
constants.ALL_STATUSES, 'ERROR')
|
||||
|
||||
self._build_instantiated_vnf_info(context, vnf_instance,
|
||||
instantiate_vnf)
|
||||
self.vnflcm_driver._vnf_instance_update(context, vnf_instance,
|
||||
self._build_instantiated_vnf_info(context, vnf_instance,
|
||||
instantiate_vnf)
|
||||
self.vnflcm_driver._vnf_instance_update(context, vnf_instance,
|
||||
task_state=None)
|
||||
|
||||
# Update vnf_lcm_op_occs table and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=None,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.INSTANTIATE,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(ex),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
except Exception as exception:
|
||||
LOG.warning("Failed to change VNF status to ERROR.\
|
||||
Exception : %s", str(exception))
|
||||
finally:
|
||||
# Update vnf_lcm_op_occs table
|
||||
# and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=None,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.INSTANTIATE,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(ex),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
|
||||
@coordination.synchronized('{vnf_instance[id]}')
|
||||
def terminate(self, context, vnf_lcm_op_occs_id,
|
||||
@ -2080,24 +2088,29 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
|
||||
)
|
||||
|
||||
except Exception as exc:
|
||||
# set vnf_status to error
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
try:
|
||||
# set vnf_status to error
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
constants.ALL_STATUSES, 'ERROR')
|
||||
|
||||
self.vnflcm_driver._vnf_instance_update(
|
||||
context, vnf_instance, task_state=None)
|
||||
|
||||
# Update vnf_lcm_op_occs table and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=None,
|
||||
operation=fields.LcmOccsOperationType.TERMINATE,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(exc),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
self.vnflcm_driver._vnf_instance_update(
|
||||
context, vnf_instance, task_state=None)
|
||||
except Exception as exception:
|
||||
LOG.warning("Failed to change VNF status to ERROR.\
|
||||
Exception : %s", str(exception))
|
||||
finally:
|
||||
# Update vnf_lcm_op_occs table and send
|
||||
# notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=None,
|
||||
operation=fields.LcmOccsOperationType.TERMINATE,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(exc),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
|
||||
def _update_vnf_attributes_stack_param(self, context, vnf_dict, vnf_id,
|
||||
heal_vnf_request, inst_vnf_info):
|
||||
@ -2183,25 +2196,30 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
|
||||
operation_state=fields.LcmOccsOperationState.COMPLETED
|
||||
)
|
||||
except Exception as ex:
|
||||
# update vnf_status to 'ERROR' and create event with 'ERROR' status
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
try:
|
||||
# update vnf_status to 'ERROR' and create
|
||||
# event with 'ERROR' status
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
constants.ALL_STATUSES, constants.ERROR)
|
||||
|
||||
# call _update_instantiated_vnf_info for notification
|
||||
self._update_instantiated_vnf_info(context, vnf_instance,
|
||||
# call _update_instantiated_vnf_info for notification
|
||||
self._update_instantiated_vnf_info(context, vnf_instance,
|
||||
heal_vnf_request)
|
||||
|
||||
# update vnf_lcm_op_occs and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.HEAL,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(ex),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
except Exception as exception:
|
||||
LOG.warning("Failed to change VNF status to ERROR.\
|
||||
Exception : %s", str(exception))
|
||||
finally:
|
||||
# update vnf_lcm_op_occs and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.HEAL,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(ex),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
|
||||
@coordination.synchronized('{vnf_instance[id]}')
|
||||
def scale(self, context, vnf_info, vnf_instance, scale_vnf_request):
|
||||
@ -2452,27 +2470,32 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook):
|
||||
operation_state=fields.LcmOccsOperationState.COMPLETED
|
||||
)
|
||||
except Exception as e:
|
||||
# update vnf_status to 'ERROR' and create event with 'ERROR' status
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
try:
|
||||
# update vnf_status to 'ERROR' and create
|
||||
# event with 'ERROR' status
|
||||
self._change_vnf_status(context, vnf_instance.id,
|
||||
constants.ALL_STATUSES, constants.ERROR)
|
||||
|
||||
LOG.error('Failed to execute operation. error={}'.format(e))
|
||||
if vnf_dict['current_error_point'] in [EP.INTERNAL_PROCESSING,
|
||||
EP.VNF_CONFIG_END]:
|
||||
self._update_instantiated_vnf_info_change_ext_conn(
|
||||
context, vnf_instance, change_ext_conn_req)
|
||||
|
||||
# update vnf_lcm_op_occs and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.CHANGE_EXT_CONN,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(e),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
LOG.error('Failed to execute operation. error={}'.format(e))
|
||||
if vnf_dict['current_error_point'] in [EP.INTERNAL_PROCESSING,
|
||||
EP.VNF_CONFIG_END]:
|
||||
self._update_instantiated_vnf_info_change_ext_conn(
|
||||
context, vnf_instance, change_ext_conn_req)
|
||||
except Exception as exception:
|
||||
LOG.warning("Failed to change VNF status to ERROR.\
|
||||
Exception : %s", str(exception))
|
||||
finally:
|
||||
# update vnf_lcm_op_occs and send notification "FAILED_TEMP"
|
||||
self._send_lcm_op_occ_notification(
|
||||
context=context,
|
||||
vnf_lcm_op_occs_id=vnf_lcm_op_occs_id,
|
||||
old_vnf_instance=old_vnf_instance,
|
||||
vnf_instance=vnf_instance,
|
||||
operation=fields.LcmOccsOperationType.CHANGE_EXT_CONN,
|
||||
operation_state=fields.LcmOccsOperationState.FAILED_TEMP,
|
||||
error=str(e),
|
||||
error_point=vnf_dict['current_error_point']
|
||||
)
|
||||
|
||||
|
||||
def init(args, **kwargs):
|
||||
|
@ -553,7 +553,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
|
||||
mock_grants.return_value = MockResponse(json_data=grant_dict)
|
||||
self.conductor.instantiate(self.context, vnf_instance, vnf_dict,
|
||||
instantiate_vnf_req, vnf_lcm_op_occs_id)
|
||||
self.assertEqual(mock_send_notification.call_count, 1)
|
||||
self.assertEqual(mock_send_notification.call_count, 2)
|
||||
self.assertEqual(mock_change_vnf_status.call_count, 1)
|
||||
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
@ -948,6 +948,94 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase):
|
||||
vnf_instance.id, mock.ANY, 'ERROR')
|
||||
mock_update_vnf_attributes.assert_called_once()
|
||||
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
'.send_notification')
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
'._update_vnf_attributes')
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
'._change_vnf_status')
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
'._build_instantiated_vnf_info')
|
||||
@mock.patch.object(objects.VnfLcmOpOcc, "save")
|
||||
@mock.patch.object(coordination.Coordinator, 'get_lock')
|
||||
@mock.patch.object(objects.LccnSubscriptionRequest,
|
||||
'vnf_lcm_subscriptions_get')
|
||||
@mock.patch('tacker.vnflcm.utils._get_vnfd_dict')
|
||||
@mock.patch('tacker.vnflcm.utils._convert_desired_capacity')
|
||||
@mock.patch('tacker.conductor.conductor_server.LOG')
|
||||
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
|
||||
@mock.patch('tacker.vnflcm.utils._get_affected_resources')
|
||||
def test_lcm_notification_exception_in_exception(
|
||||
self, mock_res, mock_vnf_by_id, mock_log,
|
||||
mock_des, mock_vnfd_dict,
|
||||
mock_vnf_lcm_subscriptions_get,
|
||||
mock_get_lock, mock_save,
|
||||
mock_build_info,
|
||||
mock_change_vnf_status,
|
||||
mock_update_vnf_attributes,
|
||||
mock_send_notification):
|
||||
lcm_op_occs_data = fakes.get_lcm_op_occs_data()
|
||||
mock_vnf_by_id.return_value = \
|
||||
objects.VnfLcmOpOcc(context=self.context,
|
||||
**lcm_op_occs_data)
|
||||
|
||||
vnf_package_vnfd = self._create_and_upload_vnf_package()
|
||||
vnf_instance_data = fake_obj.get_vnf_instance_data(
|
||||
vnf_package_vnfd.vnfd_id)
|
||||
vnf_instance = objects.VnfInstance(context=self.context,
|
||||
**vnf_instance_data)
|
||||
vnf_instance.create()
|
||||
instantiate_vnf_req = vnflcm_fakes.get_instantiate_vnf_request_obj()
|
||||
vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id
|
||||
vnf_dict = db_utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
|
||||
flavour=instantiate_vnf_req.flavour_id)
|
||||
vnf_dict['before_error_point'] = fields.ErrorPoint.INITIAL
|
||||
vnfd_key = 'vnfd_' + instantiate_vnf_req.flavour_id
|
||||
vnfd_yaml = vnf_dict['vnfd']['attributes'].get(vnfd_key, '')
|
||||
mock_vnfd_dict.return_value = yaml.safe_load(vnfd_yaml)
|
||||
mock_vnf_lcm_subscriptions_get.return_value = \
|
||||
[mock.MagicMock(**fakes.get_vnf_lcm_subscriptions())]
|
||||
mock_res.return_value = {}
|
||||
mock_change_vnf_status.side_effect = Exception
|
||||
self.conductor.instantiate(self.context, vnf_instance, vnf_dict,
|
||||
instantiate_vnf_req, vnf_lcm_op_occs_id)
|
||||
mock_change_vnf_status.assert_called_with(self.context,
|
||||
vnf_instance.id, mock.ANY, 'ERROR')
|
||||
self.assertEqual("FAILED_TEMP",
|
||||
mock_send_notification.call_args[0][1].get("operationState"))
|
||||
|
||||
heal_vnf_req = objects.HealVnfRequest(cause="healing request")
|
||||
mock_change_vnf_status.side_effect = Exception
|
||||
self.conductor.heal(self.context, vnf_instance, vnf_dict,
|
||||
heal_vnf_req, vnf_lcm_op_occs_id)
|
||||
mock_change_vnf_status.assert_called_with(self.context,
|
||||
vnf_instance.id, mock.ANY, 'ERROR')
|
||||
self.assertEqual("FAILED_TEMP",
|
||||
mock_send_notification.call_args[0][1].get("operationState"))
|
||||
|
||||
terminate_vnf_req = objects.TerminateVnfRequest(
|
||||
termination_type=fields.VnfInstanceTerminationType.GRACEFUL,
|
||||
additional_params={"key": "value"})
|
||||
self.conductor.terminate(self.context, vnf_lcm_op_occs_id,
|
||||
vnf_instance, terminate_vnf_req, vnf_dict)
|
||||
mock_change_vnf_status.assert_called_with(self.context,
|
||||
vnf_instance.id, mock.ANY, 'ERROR')
|
||||
self.assertEqual("FAILED_TEMP",
|
||||
mock_send_notification.call_args[0][1].get("operationState"))
|
||||
|
||||
change_ext_conn_req = fakes.get_change_ext_conn_request_obj()
|
||||
mock_change_vnf_status.side_effect = Exception
|
||||
self.conductor.change_ext_conn(
|
||||
self.context,
|
||||
vnf_instance,
|
||||
vnf_dict,
|
||||
change_ext_conn_req,
|
||||
vnf_lcm_op_occs_id)
|
||||
mock_change_vnf_status.assert_called_with(self.context,
|
||||
vnf_instance.id, mock.ANY, 'ERROR')
|
||||
self.assertEqual("FAILED_TEMP",
|
||||
mock_send_notification.call_args[0][1].get("operationState"))
|
||||
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
'._update_vnf_attributes')
|
||||
@mock.patch('tacker.conductor.conductor_server.Conductor'
|
||||
|
Loading…
Reference in New Issue
Block a user