From 6889e774620f247c56c85ee3fbd3a20051ee14b7 Mon Sep 17 00:00:00 2001 From: Chi Lo Date: Fri, 20 Nov 2020 12:16:04 -0800 Subject: [PATCH] Optimize CMS service to send request to region(s) Instead of broadcasting service request to all regions, CMS 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 customer logic which has been missed. Change-Id: Id86886fcb80329582baa596c1faa1d4126b0764d --- .../controllers/v1/orm/customer/enabled.py | 12 +-- .../controllers/v1/orm/customer/metadata.py | 6 +- .../controllers/v1/orm/customer/regions.py | 33 +++--- .../controllers/v1/orm/customer/root.py | 17 +-- .../controllers/v1/orm/customer/users.py | 53 +++++----- .../cms_rest/logic/customer_logic.py | 100 ++++++++++++++---- orm/tests/unit/cms/test_customer.py | 22 ++-- orm/tests/unit/cms/test_customer_logic.py | 3 +- 8 files changed, 153 insertions(+), 93 deletions(-) diff --git a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/enabled.py b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/enabled.py index 4a70616f..14e76adc 100755 --- a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/enabled.py +++ b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/enabled.py @@ -2,7 +2,7 @@ from pecan import request, rest from wsmeext.pecan import wsexpose from orm.common.orm_common.utils import api_error_utils as err_utils -from orm.common.orm_common.utils.error_base import ErrorStatus, NotAllowedError +from orm.common.orm_common.utils.error_base import ErrorStatus, NotAllowedError, NotFoundError from orm.common.orm_common.utils import utils from orm.services.customer_manager.cms_rest.logger import get_logger from orm.services.customer_manager.cms_rest.logic.customer_logic import CustomerLogic @@ -28,17 +28,17 @@ class EnabledController(rest.RestController): request.headers, customer_uuid, event_details=event_details) - except ErrorStatus as exception: - LOG.log_exception("EnabledController - Failed to Change enable", exception) + except (NotFoundError, ErrorStatus) as exception: + LOG.log_exception("EnabledController - Failed to change enable", exception) raise err_utils.get_error(request.transaction_id, - message=exception.message, + message=str(exception), status_code=exception.status_code) except Exception as exception: - LOG.log_exception("EnabledController - change enable (put) - Failed to Change enable", exception) + LOG.log_exception("EnabledController - Failed to change enable", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result diff --git a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/metadata.py b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/metadata.py index a4d494d8..06dd43a0 100755 --- a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/metadata.py +++ b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/metadata.py @@ -52,7 +52,8 @@ class MetadataController(rest.RestController): except Exception as ex: LOG.log_exception("MetaDataController - Failed to add metadata", ex) raise err_utils.get_error(request.transaction_id, - status_code=500, error_details=str(ex)) + status_code=500, + message=str(ex)) @wsexpose(CustomerResultWrapper, str, body=MetadataWrapper, rest_content_types='json') def put(self, customer_uuid, metadata): @@ -85,4 +86,5 @@ class MetadataController(rest.RestController): except Exception as ex: LOG.log_exception("MetaDataController - Failed to add metadata", ex) raise err_utils.get_error(request.transaction_id, - status_code=500, error_details=str(ex)) + status_code=500, + message=str(ex)) diff --git a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/regions.py b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/regions.py index 022156f8..cee2eec5 100755 --- a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/regions.py +++ b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/regions.py @@ -3,7 +3,7 @@ from pecan import request, rest from wsmeext.pecan import wsexpose 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, InputValueError from orm.common.orm_common.utils import utils from orm.services.customer_manager.cms_rest.controllers.v1.orm.customer.users import UserController from orm.services.customer_manager.cms_rest.logger import get_logger @@ -38,35 +38,34 @@ class RegionController(rest.RestController): event_details=event_details) except DBDuplicateEntry as exception: - LOG.log_exception("RegionController - Add Regions (post) - region already exists", exception) + LOG.log_exception("RegionController - Region already exists", exception) raise err_utils.get_error(request.transaction_id, status_code=409, - message='Region already exists', - error_details=str(exception)) + message=str(exception)) - except ErrorStatus as exception: - LOG.log_exception("CustomerController - Failed to update regions", exception) + except (NotFoundError, ErrorStatus) as exception: + LOG.log_exception("RegionController - Failed to add regions", exception) raise err_utils.get_error(request.transaction_id, message=str(exception), status_code=exception.status_code) except Exception as exception: - LOG.log_exception("RegionController - Add Regions (post) - Failed to update regions", exception) + LOG.log_exception("RegionController - Failed to add regions", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @wsexpose(RegionResultWrapper, str, body=[Region], rest_content_types='json', status_code=200) def put(self, customer_id, regions): - LOG.info("RegionController - Replace Regions (put) customer id {0} regions: {1}".format(customer_id, str(regions))) + LOG.info("RegionController - Replace Regions customer id {0} regions: {1}".format(customer_id, str(regions))) authentication.authorize(request, 'customers:update_region') self.validate_put_url() try: customer_logic = CustomerLogic() result = customer_logic.replace_regions(customer_id, regions, request.transaction_id) - LOG.info("RegionController - Replace Regions (put) finished well: " + str(result)) + LOG.info("RegionController - Replace Regions finished well: " + str(result)) event_details = 'Customer {} regions: {} updated'.format( customer_id, [r.name for r in regions]) @@ -74,17 +73,17 @@ class RegionController(rest.RestController): request.headers, customer_id, event_details=event_details) - except ErrorStatus as exception: - LOG.log_exception("CustomerController - Failed to Replace regions", exception) + except (NotFoundError, ErrorStatus) as exception: + LOG.log_exception("CustomerController - Failed to replace regions", exception) raise err_utils.get_error(request.transaction_id, message=str(exception), status_code=exception.status_code) except Exception as exception: - LOG.log_exception("RegionController - Replace Regions (put) - Failed to replace regions", exception) + LOG.log_exception("RegionController - Failed to replace regions", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @@ -108,11 +107,11 @@ class RegionController(rest.RestController): request.headers, customer_id, event_details=event_details) - except ValueError as exception: + except (InputValueError, ValueError) as exception: raise err_utils.get_error(request.transaction_id, message=str(exception), status_code=404) - except ErrorStatus as exception: + except (NotFoundError, ErrorStatus) as exception: LOG.log_exception("CustomerController - Failed to delete region", exception) raise err_utils.get_error(request.transaction_id, message=str(exception), @@ -122,7 +121,7 @@ class RegionController(rest.RestController): LOG.log_exception("RegionController - Failed in delete Region", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) @staticmethod def validate_put_url(): diff --git a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/root.py b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/root.py index 203ac7b7..b72e1420 100755 --- a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/root.py +++ b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/root.py @@ -3,7 +3,7 @@ from wsmeext.pecan import wsexpose from orm.common.orm_common.utils import api_error_utils as err_utils from orm.common.orm_common.utils.error_base import ( - ConflictError, ErrorStatus, NotAllowedError, NotFoundError) + ConflictError, ErrorStatus, NotAllowedError, NotFoundError, InputValueError) from orm.common.orm_common.utils import utils from orm.services.customer_manager.cms_rest.controllers.v1.orm.customer.enabled import EnabledController from orm.services.customer_manager.cms_rest.controllers.v1.orm.customer.metadata import MetadataController @@ -42,7 +42,7 @@ class CustomerController(rest.RestController): LOG.log_exception("CustomerController - Failed to GetCustomerDetails", str(exception)) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @@ -78,15 +78,15 @@ class CustomerController(rest.RestController): raise err_utils.get_error(request.transaction_id, message=str(exception), status_code=exception.status_code) - except ValueError as exception: + except (InputValueError, ValueError) as exception: raise err_utils.get_error(request.transaction_id, status_code=400, - error_details=str(exception)) + message=str(exception)) except Exception as exception: LOG.log_exception("CustomerController - Failed to CreateCustomer", str(exception)) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) @wsexpose(CustomerResultWrapper, str, body=Customer, rest_content_types='json', status_code=200) def put(self, customer_id, customer): @@ -115,7 +115,7 @@ class CustomerController(rest.RestController): LOG.log_exception("CustomerController - Failed to UpdateCustomer", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @@ -142,13 +142,14 @@ class CustomerController(rest.RestController): except ErrorStatus as exception: LOG.log_exception("CustomerController - Failed to GetCustomerlist", exception) raise err_utils.get_error(request.transaction_id, + message=str(exception), status_code=exception.status_code) except Exception as exception: LOG.log_exception("CustomerController - Failed to GetCustomerlist", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) @wsexpose(None, str, rest_content_types='json', status_code=204) def delete(self, customer_id): @@ -177,4 +178,4 @@ class CustomerController(rest.RestController): exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) diff --git a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/users.py b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/users.py index 0c9be970..5458701b 100755 --- a/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/users.py +++ b/orm/services/customer_manager/cms_rest/controllers/v1/orm/customer/users.py @@ -2,7 +2,10 @@ from pecan import request, rest from wsmeext.pecan import wsexpose 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, + NotAllowedError) from orm.common.orm_common.utils import utils from orm.services.customer_manager.cms_rest.logger import get_logger from orm.services.customer_manager.cms_rest.logic.customer_logic import CustomerLogic @@ -22,14 +25,14 @@ class DefaultUserController(rest.RestController): @wsexpose(UserResultWrapper, str, body=[User], rest_content_types='json', status_code=200) def put(self, customer_id, users): # replace default users to customer - LOG.info("DefaultUserController - Replace DefaultUsers (put) customer id {0} users: {1}".format(customer_id, str(users))) + LOG.info("DefaultUserController - Replace DefaultUsers customer id {0} users: {1}".format(customer_id, str(users))) authentication.authorize(request, 'customers:update_default_user') try: customer_logic = CustomerLogic() result = customer_logic.replace_default_users(customer_id, users, request.transaction_id) - LOG.info("DefaultUserController - Replace DefaultUsers (put) Finished well customer id {0} users: {1}".format(customer_id, str(users))) + LOG.info("DefaultUserController - Replace DefaultUsers finished well customer id {0} users: {1}".format(customer_id, str(users))) - except ErrorStatus as exception: + except (NotFoundError, ErrorStatus) as exception: LOG.log_exception("DefaultUserController - Failed to replace default users", exception) raise err_utils.get_error(request.transaction_id, message=exception.message, @@ -46,27 +49,27 @@ class DefaultUserController(rest.RestController): LOG.log_exception("DefaultUserController - Failed to replace default users", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @wsexpose(UserResultWrapper, str, body=[User], rest_content_types='json', status_code=200) def post(self, customer_id, users): # add default users to customer - LOG.info("DefaultUserController - Add DefaultUsers (put) customer id {0} users: {1}".format(customer_id, str(users))) + LOG.info("DefaultUserController - Add DefaultUsers customer id {0} users: {1}".format(customer_id, str(users))) authentication.authorize(request, 'customers:add_default_user') try: customer_logic = CustomerLogic() result = customer_logic.add_default_users(customer_id, users, request.transaction_id) - LOG.info("DefaultUserController - Add DefaultUsers (post) Finished well customer id {0} users: {1}".format( + LOG.info("DefaultUserController - Add DefaultUsers finished well customer id {0} users: {1}".format( customer_id, str(users))) - except ErrorStatus as exception: + except (ConflictError, ErrorStatus) as exception: LOG.log_exception("DefaultUserController - Failed to add default users", exception) raise err_utils.get_error(request.transaction_id, message=exception.message, status_code=exception.status_code) - except LookupError as exception: + except (LookupError, NotFoundError) as exception: LOG.log_exception("DefaultUserController - {0}".format(exception.message), exception) raise err_utils.get_error(request.transaction_id, message=exception.message, @@ -77,18 +80,18 @@ class DefaultUserController(rest.RestController): LOG.log_exception("DefaultUserController - Failed to add default users", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @wsexpose(None, str, str, status_code=204) def delete(self, customer_id, user_id): - LOG.info("DefaultUserController - Delete DefaultUsers (delete) customer id {0} user_id: {1}".format(customer_id, user_id)) + LOG.info("DefaultUserController - Delete DefaultUsers customer id {0} user_id: {1}".format(customer_id, user_id)) authentication.authorize(request, 'customers:delete_default_user') try: customer_logic = CustomerLogic() customer_logic.delete_default_users(customer_id, user_id, request.transaction_id) - LOG.info("DefaultUserController - Delete DefaultUsers (delete) Finished well customer id {0} user_id: {1}".format(customer_id, user_id)) + LOG.info("DefaultUserController - Delete DefaultUsers finished well customer id {0} user_id: {1}".format(customer_id, user_id)) utils.audit_trail('delete default users', request.transaction_id, request.headers, customer_id) except ErrorStatus as exception: @@ -104,10 +107,10 @@ class DefaultUserController(rest.RestController): status_code=404) except Exception as exception: - LOG.log_exception("DefaultUserController - Failed in Delete default User", exception) + LOG.log_exception("DefaultUserController - Failed in delete default User", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) class UserController(rest.RestController): @@ -144,7 +147,7 @@ class UserController(rest.RestController): request.headers, customer_id, event_details=event_details) - except ErrorStatus as exception: + except (ConflictError, ErrorStatus) as exception: LOG.log_exception("DefaultUserController - Failed to {}".format(event), exception) raise err_utils.get_error(request.transaction_id, message=exception.message, @@ -159,17 +162,17 @@ class UserController(rest.RestController): except Exception as exception: if exception.inner_exception.orig[0] == 1452: result = UserResultWrapper(transaction_id="Users Not Added", users=[]) - LOG.log_exception("UserController - Failed to Add Users (post)", exception) + LOG.log_exception("UserController - Failed to Add Users ", exception) LOG.log_exception("Region specified must be added to customer first.", exception) raise err_utils.get_error(request.transaction_id, status_code=500, message="Region specified must be added to customer first.") else: result = UserResultWrapper(transaction_id="Users Not Added", users=[]) - LOG.log_exception("UserController - Failed to Add Users (post)", exception) + LOG.log_exception("UserController - Failed to Add Users ", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @@ -196,7 +199,7 @@ class UserController(rest.RestController): message=exception.message, status_code=exception.status_code) - except LookupError as exception: + except (LookupError, NotFoundError) as exception: LOG.log_exception("DefaultUserController - {0}".format(exception.message), exception) raise err_utils.get_error(request.transaction_id, message=exception.message, @@ -207,18 +210,18 @@ class UserController(rest.RestController): LOG.log_exception("UserController - Failed to Replaced Users", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) return result @wsexpose(None, str, str, str, status_code=204) def delete(self, customer_id, region_id, user_id): - LOG.info("UserController - Delete User (delete) customer id {0} region_id: {1} user_id: {2}".format(customer_id, region_id, user_id)) + LOG.info("UserController - Delete User customer id {0} region_id: {1} user_id: {2}".format(customer_id, region_id, user_id)) authentication.authorize(request, 'customers:delete_region_user') try: customer_logic = CustomerLogic() customer_logic.delete_users(customer_id, region_id, user_id, request.transaction_id) - LOG.info("UserController - Delete User (delete) Finished well customer id {0} region_id: {1} user_id: {2}".format(customer_id, region_id, user_id)) + LOG.info("UserController - Delete User finished well customer id {0} region_id: {1} user_id: {2}".format(customer_id, region_id, user_id)) event_details = 'Customer {} user: {} deleted in region {}'.format( customer_id, user_id, region_id) @@ -226,7 +229,7 @@ class UserController(rest.RestController): request.headers, customer_id, event_details=event_details) - except ErrorStatus as exception: + except (NotAllowedError, ErrorStatus) as exception: LOG.log_exception("DefaultUserController - Failed to delete users", exception) raise err_utils.get_error(request.transaction_id, message=exception.message, @@ -239,7 +242,7 @@ class UserController(rest.RestController): status_code=404) except Exception as exception: - LOG.log_exception("UserController - Failed to Delete User (delete) ", exception) + LOG.log_exception("UserController - Failed to delete User ", exception) raise err_utils.get_error(request.transaction_id, status_code=500, - error_details=str(exception)) + message=str(exception)) diff --git a/orm/services/customer_manager/cms_rest/logic/customer_logic.py b/orm/services/customer_manager/cms_rest/logic/customer_logic.py index b726d647..ae1344a1 100755 --- a/orm/services/customer_manager/cms_rest/logic/customer_logic.py +++ b/orm/services/customer_manager/cms_rest/logic/customer_logic.py @@ -1,3 +1,4 @@ +import json import oslo_db import pecan from pecan import conf, request @@ -214,7 +215,8 @@ class CustomerLogic(object): new_customer_dict["regions"]) customer_result_wrapper = build_response(customer_uuid, transaction_id, 'update') - datamanager.flush() # i want to get any exception created by this insert + # Flush to get any exception, if any, created by this insert + datamanager.flush() if not len(new_customer_dict['regions']) == 0: RdsProxy.send_customer_dict(new_customer_dict, transaction_id, "PUT") datamanager.commit() @@ -226,21 +228,48 @@ class CustomerLogic(object): datamanager.rollback() raise - def resolve_regions_actions(self, old_regions_dict, new_regions_dict): + def sort_region_attributes(self, region): + sorted_region = region + # sort quotas attributes in alphabetical order + # and users by user id + sorted_quotas_list = sorted(region['quotas'], key=lambda d: sorted(d.items())) + sorted_region['quotas'] = sorted_quotas_list + + sorted_users_list = sorted(region['users'], key=lambda k: k['id']) + sorted_region['users'] = sorted_users_list + + return json.dumps(sorted_region, sort_keys=True) + + def resolve_regions_actions(self, old_regions_dict, new_regions_dict, deep_check=False): + requested_regions = [] + for region in new_regions_dict: old_region = next((r for r in old_regions_dict if r["name"] == region["name"]), None) if old_region: - region["action"] = "modify" + if deep_check: + # For region that is found in both dictionary, verify if they + # are identical. If they are, skip adding to the requested + # regions list since RDS should not need send a request + # to a region for no change. + old_region_attributes = self.sort_region_attributes(old_region) + region_attributes = self.sort_region_attributes(region) + if old_region_attributes != region_attributes: + region["action"] = "modify" + requested_regions.append(region) + else: + region["action"] = "modify" + requested_regions.append(region) else: region["action"] = "create" + requested_regions.append(region) for region in old_regions_dict: new_region = next((r for r in new_regions_dict if r["name"] == region["name"]), None) if not new_region: region["action"] = "delete" - new_regions_dict.append(region) + requested_regions.append(region) - return new_regions_dict + return requested_regions def add_users(self, customer_uuid, region_name, users, transaction_id, p_datamanager=None): datamanager = None @@ -274,8 +303,20 @@ class CustomerLogic(object): self.add_user_and_roles_to_db(users, default_users, customer_id, region_id, datamanager) timestamp = utils.get_time_human() - datamanager.flush() # i want to get any exception created by this insert - RdsProxy.send_customer(customer, transaction_id, "PUT") + + # Flush to get any exception, if any, created by this insert + datamanager.flush() + + # Modify dictionary to only have the requested region + customer_dict = customer.get_proxy_dict() + requested_regions = [] + for region in customer_dict['regions']: + if region['name'] == region_name: + requested_regions.append(region) + break + customer_dict['regions'] = requested_regions + + RdsProxy.send_customer_dict(customer_dict, transaction_id, "PUT") if p_datamanager is None: datamanager.commit() @@ -310,9 +351,9 @@ class CustomerLogic(object): if region_id is None: raise NotFoundError("region {} not found".format(region_name)) - # delete older default user + # delete older region user user_role_record = datamanager.get_record('user_role') - user_role_record.delete_all_users_from_region(customer_uuid, region_name) # -1 is default region + user_role_record.delete_all_users_from_region(customer_uuid, region_name) result = self.add_users(customer_uuid, region_name, users, transaction_id, datamanager) datamanager.commit() return result @@ -347,7 +388,16 @@ class CustomerLogic(object): % (user_id, region_id, customer_uuid) raise NotAllowedError(message) - RdsProxy.send_customer(customer, transaction_id, "PUT") + # Modify dictionary to only have the requested region + customer_dict = customer.get_proxy_dict() + requested_regions = [] + for region in customer_dict['regions']: + if region['name'] == region_id: + requested_regions.append(region) + break + customer_dict['regions'] = requested_regions + + RdsProxy.send_customer_dict(customer_dict, transaction_id, "PUT") datamanager.commit() LOG.info("User {0} from region {1} in customer {2} deleted". @@ -484,7 +534,6 @@ class CustomerLogic(object): datamanager = DataManager() customer_record = datamanager.get_record('customer') try: - # TODO DataBase action customer_id = datamanager.get_customer_id_by_uuid(customer_uuid) if customer_id is None: raise NotFoundError("Customer with id {} does not exist".format( @@ -504,19 +553,20 @@ class CustomerLogic(object): self.add_regions_to_db(regions, customer_id, datamanager, default_users) datamanager.commit() - datamanager.session.expire(sql_customer) sql_customer = datamanager.get_customer_by_id(customer_id) - new_customer_dict = sql_customer.get_proxy_dict() + requested_regions = [] for region in new_customer_dict["regions"]: new_region = next((r for r in regions if r.name == region["name"]), None) if new_region: region["action"] = "create" - else: - region["action"] = "modify" + requested_regions.append(region) + + # Modify dictionary to only have the requested region + new_customer_dict['regions'] = requested_regions timestamp = utils.get_time_human() RdsProxy.send_customer_dict(new_customer_dict, transaction_id, "POST") @@ -561,20 +611,22 @@ class CustomerLogic(object): datamanager.session.expire(old_sql_customer) customer_region.delete_all_regions_for_customer(customer_id) - self.add_regions_to_db(regions, customer_id, datamanager, default_users) + timestamp = utils.get_time_human() new_sql_customer = datamanager.get_customer_by_id(customer_id) - new_customer_dict = new_sql_customer.get_proxy_dict() - datamanager.flush() # i want to get any exception created by this insert - + # Flush to get any exception, if any, created by this insert + datamanager.flush() new_customer_dict["regions"] = self.resolve_regions_actions(old_customer_dict["regions"], - new_customer_dict["regions"]) + new_customer_dict["regions"], + deep_check=True) + + if not len(new_customer_dict['regions']) == 0: + RdsProxy.send_customer_dict(new_customer_dict, transaction_id, "PUT") - RdsProxy.send_customer_dict(new_customer_dict, transaction_id, "PUT") datamanager.commit() base_link = '{0}{1}/'.format(conf.server.host_ip, @@ -612,9 +664,15 @@ class CustomerLogic(object): regions = get_regions_of_group(region.name) else: regions = [region_id] + + requested_regions = [] for region in customer_dict['regions']: if region['name'] in regions: region['action'] = 'delete' + requested_regions.append(region) + + # Modify dictionary to only have the requested region + customer_dict['regions'] = requested_regions RdsProxy.send_customer_dict(customer_dict, transaction_id, "PUT") if force_delete: diff --git a/orm/tests/unit/cms/test_customer.py b/orm/tests/unit/cms/test_customer.py index 0b817432..68b557cf 100755 --- a/orm/tests/unit/cms/test_customer.py +++ b/orm/tests/unit/cms/test_customer.py @@ -1,7 +1,7 @@ import requests import sqlalchemy -from orm.common.orm_common.utils.error_base import ErrorStatus +from orm.common.orm_common.utils.error_base import ErrorStatus, ConflictError from orm.services.customer_manager.cms_rest.controllers.v1.orm.customer import root from orm.services.customer_manager.cms_rest.model import Models from orm.tests.unit.cms import FunctionalTest, test_utils @@ -58,14 +58,9 @@ class TestCustomerController(FunctionalTest): # assert self.assertEqual(response.status_int, 500) - @mock.patch.object(root, 'CustomerLogic') - def test_create_flavor_duplicate_name(self, mock_customerlogic): - my_mock = mock.MagicMock() - my_mock.create_customer = mock.MagicMock( - side_effect=sqlalchemy.exc.IntegrityError( - 'a', 'b', - 'Duplicate entry \'customer\' for key \'name_idx\'')) - mock_customerlogic.return_value = my_mock + def test_create_customer_duplicate_name(self): + requests.post = mock.MagicMock() + root.CustomerLogic.return_error = 3 root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 409)) @@ -74,7 +69,7 @@ class TestCustomerController(FunctionalTest): expect_errors=True) self.assertEqual(response.status_int, 409) - def test_create_flavor_duplicate_uuid(self): + def test_create_customer_duplicate_uuid(self): CUSTOMER_JSON['uuid'] = 'test' create_or_validate_uuid = root.utils.create_or_validate_uuid @@ -91,7 +86,7 @@ class TestCustomerController(FunctionalTest): self.assertEqual(response.status_int, 409) @mock.patch.object(root, 'CustomerLogic') - def test_create_flavor_other_error(self, mock_customerlogic): + def test_create_customer_other_error(self, mock_customerlogic): my_mock = mock.MagicMock() my_mock.create_customer = mock.MagicMock( side_effect=sqlalchemy.exc.IntegrityError( @@ -293,7 +288,7 @@ def get_mock_customer_logic(): customer_logic_mock.delete_customer_by_uuid.side_effect = SystemError() customer_logic_mock.get_customer_list_by_criteria.side_effect = SystemError() - else: + elif root.CustomerLogic.return_error == 2: customer_logic_mock.create_customer.side_effect = ErrorStatus(status_code=404) customer_logic_mock.update_customer.side_effect = ErrorStatus(status_code=404) customer_logic_mock.get_customer.side_effect = ErrorStatus(status_code=404) @@ -301,6 +296,9 @@ def get_mock_customer_logic(): status_code=409) customer_logic_mock.get_customer_list_by_criteria.side_effect = ErrorStatus(status_code=404) + else: + customer_logic_mock.create_customer.side_effect = ConflictError() + return customer_logic_mock diff --git a/orm/tests/unit/cms/test_customer_logic.py b/orm/tests/unit/cms/test_customer_logic.py index c7e04a16..42fa8e05 100755 --- a/orm/tests/unit/cms/test_customer_logic.py +++ b/orm/tests/unit/cms/test_customer_logic.py @@ -226,7 +226,7 @@ class TestCustomerLogic(FunctionalTest): assert record_mock.delete_user_from_region.called assert data_manager_mock.commit.called - assert customer_logic.RdsProxy.send_customer.called + assert customer_logic.RdsProxy.send_customer_dict.called def test_delete_users_fail_notfound(self): global rowcount @@ -363,7 +363,6 @@ class TestCustomerLogic(FunctionalTest): logic.replace_regions('customer_uuid', regions, 'transaction_id') assert data_manager_mock.commit.called - assert customer_logic.RdsProxy.send_customer_dict.called assert record_mock.delete_all_regions_for_customer.called def test_replace_regions_fail(self):