Optimize FMS service to send request to region(s)

Instead of broadcasting service request to all regions, FMS service
will now send request to only affected regions.  Un-affected regions
will not receive request to perform a no-op.

This patch also catches exceptions from flavor logic which has
been missed.

Change-Id: Id285ba98b8a53f11cada05a7fb380f6facf69594
This commit is contained in:
Chi Lo 2020-12-07 16:04:42 -08:00
parent 6889e77462
commit 6b91d346a4
6 changed files with 71 additions and 47 deletions

View File

@ -1,6 +1,10 @@
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import api_error_utils as err_utils
from orm.common.orm_common.utils.error_base import ErrorStatus, NotAllowedError, NotFoundError, InputValueError
from orm.common.orm_common.utils.error_base import (ErrorStatus,
NotAllowedError,
NotFoundError,
InputValueError,
ConflictError)
from orm.common.orm_common.utils import utils as common_utils
from orm.services.flavor_manager.fms_rest.controllers.v1.orm.flavors.os_extra_specs import OsExtraSpecsController
from orm.services.flavor_manager.fms_rest.controllers.v1.orm.flavors.regions import RegionController
@ -54,7 +58,7 @@ class FlavorController(rest.RestController):
event_details=event_details)
return result
except (ErrorStatus, NotFoundError) as exception:
except (ErrorStatus, NotFoundError, ConflictError) as exception:
LOG.error("FlavorController - Failed to CreateFlavor: " + str(exception))
raise err_utils.get_error(request.transaction_id,
message=str(exception),
@ -116,7 +120,7 @@ class FlavorController(rest.RestController):
vm_type, vnf_name,
starts_with, contains, alias)
return result
except ErrorStatus as exception:
except (ErrorStatus, NotFoundError) as exception:
LOG.error("FlavorController - Failed to GetFlavorlist: " + str(exception))
raise err_utils.get_error(request.transaction_id,
message=str(exception),

View File

@ -2,7 +2,7 @@
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import api_error_utils as err_utils
from orm.common.orm_common.utils.error_base import ErrorStatus
from orm.common.orm_common.utils.error_base import ErrorStatus, NotFoundError
from orm.services.flavor_manager.fms_rest.data.wsme.models import ExtraSpecsWrapper
from orm.services.flavor_manager.fms_rest.logger import get_logger
from orm.services.flavor_manager.fms_rest.utils import authentication
@ -51,7 +51,7 @@ class OsExtraSpecsController(rest.RestController):
request.headers, flavor_id)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"OsExtraSpecsController - Failed to get extra specs", exception)
raise err_utils.get_error(request.transaction_id,
@ -63,7 +63,7 @@ class OsExtraSpecsController(rest.RestController):
"OsExtraSpecsController - Failed to get extra specs", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(ExtraSpecsWrapper, str, body=ExtraSpecsWrapper, rest_content_types='json', status_code=201)
def post(self, flavor_id, extra_specs_wrapper):
@ -85,7 +85,7 @@ class OsExtraSpecsController(rest.RestController):
request.headers, flavor_id)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"OsExtraSpecsController - Failed to add extra specs", exception)
raise err_utils.get_error(request.transaction_id,
@ -97,7 +97,7 @@ class OsExtraSpecsController(rest.RestController):
"OsExtraSpecsController - Failed to add extra specs", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(None, str, str, rest_content_types='json', status_code=204)
def delete(self, flavor_id, extra_spec=None):
@ -117,7 +117,7 @@ class OsExtraSpecsController(rest.RestController):
request.headers, flavor_id)
return
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"OsExtraSpecsController - Failed to delete extra specs", exception)
raise err_utils.get_error(request.transaction_id,
@ -129,7 +129,7 @@ class OsExtraSpecsController(rest.RestController):
exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(ExtraSpecsWrapper, str, body=ExtraSpecsWrapper, rest_content_types='json',
status_code=200)
@ -154,7 +154,7 @@ class OsExtraSpecsController(rest.RestController):
request.headers, flavor_id)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"OsExtraSpecsController - Failed to update extra specs", exception)
raise err_utils.get_error(request.transaction_id,
@ -166,4 +166,4 @@ class OsExtraSpecsController(rest.RestController):
"OsExtraSpecsController - Failed to update extra specs", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))

View File

@ -1,6 +1,9 @@
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import api_error_utils as err_utils
from orm.common.orm_common.utils.error_base import ErrorStatus, NotFoundError
from orm.common.orm_common.utils.error_base import (ErrorStatus,
NotFoundError,
InputValueError,
ConflictError)
from orm.services.flavor_manager.fms_rest.data.wsme.models import RegionWrapper
from orm.services.flavor_manager.fms_rest.logger import get_logger
from orm.services.flavor_manager.fms_rest.utils import authentication
@ -37,7 +40,8 @@ class RegionController(rest.RestController):
event_details=event_details)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus,
InputValueError, ConflictError) as exception:
LOG.log_exception("RegionController - Failed to add region",
exception)
raise err_utils.get_error(request.transaction_id,
@ -49,7 +53,7 @@ class RegionController(rest.RestController):
exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(None, str, str, str, rest_content_types='json', status_code=204)
def delete(self, flavor_id, region_name, force_delete='False'):
@ -84,4 +88,4 @@ class RegionController(rest.RestController):
exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))

View File

@ -2,7 +2,7 @@
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import api_error_utils as err_utils
from orm.common.orm_common.utils.error_base import ErrorStatus
from orm.common.orm_common.utils.error_base import ErrorStatus, NotFoundError
from orm.services.flavor_manager.fms_rest.data.wsme.models import TagsWrapper
from orm.services.flavor_manager.fms_rest.logger import get_logger
from orm.services.flavor_manager.fms_rest.utils import authentication
@ -35,7 +35,7 @@ class TagsController(rest.RestController):
request.headers, flavor_id)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception("TagsController - Failed to add tags", exception)
raise err_utils.get_error(request.transaction_id,
message=exception.message,
@ -44,7 +44,7 @@ class TagsController(rest.RestController):
LOG.log_exception("TagsController - Failed to add tags", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(None, str, str, rest_content_types='json', status_code=204)
def delete(self, flavor_id, tag_to_delete=None):
@ -63,22 +63,22 @@ class TagsController(rest.RestController):
utils.audit_trail('delete tags', request.transaction_id,
request.headers, flavor_id, 'Saved to DB')
except ErrorStatus as exp:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"TagsController - Failed to delete tags", exp)
"TagsController - Failed to delete tags", exception)
utils.audit_trail('delete tags', request.transaction_id,
request.headers, flavor_id)
raise err_utils.get_error(request.transaction_id,
message=exp.message,
status_code=exp.status_code)
except Exception as exp:
message=exception.message,
status_code=exception.status_code)
except Exception as exception:
LOG.log_exception("TagsController - Failed to delete tags",
exp)
exception)
utils.audit_trail('delete tags', request.transaction_id,
request.headers, flavor_id)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exp))
message=str(exception))
return
@ -96,7 +96,7 @@ class TagsController(rest.RestController):
utils.audit_trail('update tags', request.transaction_id, request.headers, flavor_id)
return result
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception("TagsController - Failed to update tags", exception)
raise err_utils.get_error(request.transaction_id,
message=exception.message,
@ -106,7 +106,7 @@ class TagsController(rest.RestController):
LOG.log_exception("TagsController - Failed to update tags", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(TagsWrapper, str, rest_content_types='json', status_code=200)
def get(self, flavor_id):
@ -121,7 +121,7 @@ class TagsController(rest.RestController):
request.headers, flavor_id)
return TagsWrapper(result)
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus) as exception:
LOG.log_exception(
"TagsController - Failed to get tags", exception)
raise err_utils.get_error(request.transaction_id,
@ -133,4 +133,4 @@ class TagsController(rest.RestController):
"TagsController - Failed to get tags", exception)
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))

View File

@ -1,6 +1,9 @@
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import api_error_utils as err_utils
from orm.common.orm_common.utils.error_base import ErrorStatus, NotFoundError
from orm.common.orm_common.utils.error_base import (ErrorStatus,
NotFoundError,
ConflictError,
InputValueError)
from orm.services.flavor_manager.fms_rest.data.wsme.models import TenantWrapper
from orm.services.flavor_manager.fms_rest.logger import get_logger
from orm.services.flavor_manager.fms_rest.utils import authentication
@ -33,13 +36,13 @@ class TenantController(rest.RestController):
request.headers, flavor_id,
event_details=event_details)
return result
except ValueError as exception:
except (InputValueError, ValueError) as exception:
LOG.log_exception("TenantController - Failed to add tenants", str(exception))
raise err_utils.get_error(request.transaction_id,
message=str(exception),
status_code=400)
except ErrorStatus as exception:
except (NotFoundError, ErrorStatus, ConflictError) as exception:
LOG.log_exception("TenantController - Failed to add tenants", str(exception))
raise err_utils.get_error(request.transaction_id,
message=str(exception),
@ -49,7 +52,7 @@ class TenantController(rest.RestController):
LOG.log_exception("TenantController - Failed to add tenants", str(exception))
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(None, str, str, rest_content_types='json', status_code=204)
def delete(self, flavor_id, tenant_id):
@ -74,15 +77,20 @@ class TenantController(rest.RestController):
raise err_utils.get_error(request.transaction_id,
message=str(exception),
status_code=exception.status_code)
except ValueError as exception:
LOG.log_exception("TenantController - Failed to delete tenant", str(exception))
raise err_utils.get_error(request.transaction_id,
message=str(exception),
status_code=400)
except Exception as exception:
LOG.log_exception("TenantController - Failed to delete tenant", str(exception))
raise err_utils.get_error(request.transaction_id,
status_code=500,
error_details=str(exception))
message=str(exception))
@wsexpose(str, str, rest_content_types='json')
def get(self, flavor_id):
LOG.error("Get tenants is not supported")
raise err_utils.get_error(request.transaction_id,
status_code=405)
status_code=403)

View File

@ -126,12 +126,14 @@ def create_flavor(flavor, flavor_uuid, transaction_id):
def send_to_rds_if_needed(sql_flavor,
existing_region_names,
http_action,
transaction_id):
transaction_id,
optimized=False):
rds_proxy = di.resolver.unpack(send_to_rds_if_needed)
if (sql_flavor.flavor_regions and len(sql_flavor.flavor_regions) > 0) \
or len(existing_region_names) > 0:
flavor_dict = sql_flavor.todict()
update_region_actions(flavor_dict, existing_region_names, http_action)
update_region_actions(flavor_dict, existing_region_names, http_action,
optimized)
LOG.debug("Flavor is valid to send to RDS - sending to RDS Proxy ")
rds_proxy.send_flavor(flavor_dict, transaction_id, http_action)
else:
@ -156,7 +158,8 @@ def update_flavor(flavor, flavor_uuid, transaction_id): # pragma: no cover
flavor_rec = datamanager.get_record('flavor')
db_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if db_flavor is None:
raise EntityNotFound("Flavor {0} not found in database".format(flavor_uuid))
raise EntityNotFound(
"Flavor {0} not found in database".format(flavor_uuid))
existing_region_names = db_flavor.get_existing_region_names()
@ -283,7 +286,6 @@ def add_regions(flavor_uuid, regions, transaction_id):
for tenant in sql_flavor.flavor_tenants:
flvr_tenant_list = sql_flavor.get_existing_tenant_ids()
# existing_region_names = db_flavor.get_existing_region_names()
# add existing flavor regions to flvr_region_list in order for
# the validate_tenants_regions_list to process correctly
flvr_region_list = sql_flavor.get_existing_region_names()
@ -297,8 +299,8 @@ def add_regions(flavor_uuid, regions, transaction_id):
if tenant not in valid_tenants_list:
sql_flavor.remove_tenant(tenant)
send_to_rds_if_needed(
sql_flavor, existing_region_names, "put", transaction_id)
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id, optimized=True)
datamanager.commit()
@ -379,9 +381,8 @@ def delete_region(flavor_uuid, region_name, transaction_id, force_delete):
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id)
transaction_id, optimized=True)
if force_delete:
datamanager.commit()
@ -1057,17 +1058,22 @@ def calculate_name(flavor):
return name
def update_region_actions(flavor_dict, existing_region_names, action="put"):
def update_region_actions(flavor_dict, existing_region_names, action,
optimized):
if action == "delete":
set_regions_action(flavor_dict, "delete")
elif action == "post":
set_regions_action(flavor_dict, "create")
else: # put
requested_regions = []
for region in flavor_dict["regions"]:
if region["name"] in existing_region_names:
region["action"] = "modify"
if not optimized:
requested_regions.append(region)
else:
region["action"] = "create"
requested_regions.append(region)
# add deleted regions
for exist_region_name in existing_region_names:
@ -1075,8 +1081,10 @@ def update_region_actions(flavor_dict, existing_region_names, action="put"):
flavor_dict["regions"]):
continue
else:
flavor_dict["regions"].append({"name": exist_region_name,
"action": "delete"})
requested_regions.append({"name": exist_region_name,
"action": "delete"})
flavor_dict["regions"] = requested_regions
def region_name_exist_in_regions(region_name, regions):