Move the DesignateAdapter to return non-wrapped objects

Change-Id: Iaab9514fc5f443cc6dd09c10f928c042b9dbcfb7
Partially-Implements: blueprint validation-cleanup
This commit is contained in:
Graham Hayes 2015-03-13 19:47:38 +00:00
parent 0c982b7d8d
commit fce8049cb6
4 changed files with 46 additions and 93 deletions

View File

@ -21,39 +21,3 @@ LOG = logging.getLogger(__name__)
class APIv1Adapter(base.DesignateAdapter): class APIv1Adapter(base.DesignateAdapter):
ADAPTER_FORMAT = 'API_v1' ADAPTER_FORMAT = 'API_v1'
#####################
# Rendering methods #
#####################
@classmethod
def render(cls, object, *args, **kwargs):
return super(APIv1Adapter, cls).render(
cls.ADAPTER_FORMAT, object, *args, **kwargs)
@classmethod
def _render_list(cls, list_object, *args, **kwargs):
inner = cls._render_inner_list(list_object, *args, **kwargs)
return {cls.MODIFICATIONS['options']['collection_name']: inner}
@classmethod
def _render_object(cls, object, *args, **kwargs):
return cls._render_inner_object(object, *args, **kwargs)
#####################
# Parsing methods #
#####################
@classmethod
def parse(cls, values, output_object, *args, **kwargs):
return super(APIv1Adapter, cls).parse(
cls.ADAPTER_FORMAT, values, output_object, *args, **kwargs)
@classmethod
def _parse_list(cls, values, output_object, *args, **kwargs):
return cls._parse_inner_list(values, output_object, *args, **kwargs)
@classmethod
def _parse_object(cls, values, output_object, *args, **kwargs):
return cls._parse_inner_object(values, output_object, *args, **kwargs)

View File

@ -34,37 +34,32 @@ class APIv2Adapter(base.DesignateAdapter):
# Rendering methods # # Rendering methods #
##################### #####################
@classmethod
def render(cls, object, *args, **kwargs):
return super(APIv2Adapter, cls).render(
cls.ADAPTER_FORMAT, object, *args, **kwargs)
@classmethod @classmethod
def _render_list(cls, list_object, *args, **kwargs): def _render_list(cls, list_object, *args, **kwargs):
inner = cls._render_inner_list(list_object, *args, **kwargs) r_list = super(APIv2Adapter, cls)._render_list(
outer = {} list_object, *args, **kwargs)
if cls.MODIFICATIONS['options'].get('links', True): if cls.MODIFICATIONS['options'].get('links', True)\
outer['links'] = cls._get_collection_links( and 'request' in kwargs:
r_list['links'] = cls._get_collection_links(
list_object, kwargs['request']) list_object, kwargs['request'])
# Check if we should include metadata # Check if we should include metadata
if isinstance(list_object, obj_base.PagedListObjectMixin): if isinstance(list_object, obj_base.PagedListObjectMixin):
metadata = {} metadata = {}
metadata['total_count'] = list_object.total_count metadata['total_count'] = list_object.total_count
outer['metadata'] = metadata r_list['metadata'] = metadata
outer[cls.MODIFICATIONS['options']['collection_name']] = inner return r_list
return outer
@classmethod @classmethod
def _render_object(cls, object, *args, **kwargs): def _render_object(cls, object, *args, **kwargs):
inner = cls._render_inner_object(object, *args, **kwargs) obj = super(APIv2Adapter, cls)._render_object(object, *args, **kwargs)
if cls.MODIFICATIONS['options'].get('links', True): if cls.MODIFICATIONS['options'].get('links', True)\
inner['links'] = cls._get_resource_links(object, kwargs['request']) and 'request' in kwargs:
obj['links'] = cls._get_resource_links(object, kwargs['request'])
return {cls.MODIFICATIONS['options']['resource_name']: inner} return obj
##################### #####################
# Parsing methods # # Parsing methods #
@ -75,16 +70,6 @@ class APIv2Adapter(base.DesignateAdapter):
return super(APIv2Adapter, cls).parse( return super(APIv2Adapter, cls).parse(
cls.ADAPTER_FORMAT, values, output_object, *args, **kwargs) cls.ADAPTER_FORMAT, values, output_object, *args, **kwargs)
@classmethod
def _parse_list(cls, values, output_object, *args, **kwargs):
return cls._parse_inner_list(values, output_object, *args, **kwargs)
@classmethod
def _parse_object(cls, values, output_object, *args, **kwargs):
inner = values[cls.MODIFICATIONS['options']['resource_name']]
return cls._parse_inner_object(inner, output_object, *args, **kwargs)
##################### #####################
# Link methods # # Link methods #
##################### #####################

View File

@ -57,7 +57,10 @@ class DesignateAdapter(object):
@classmethod @classmethod
def get_object_adapter(cls, format_, object): def get_object_adapter(cls, format_, object):
key = '%s:%s' % (format_, object.obj_name()) if isinstance(object, objects.DesignateObject):
key = '%s:%s' % (format_, object.obj_name())
else:
key = '%s:%s' % (format_, object)
try: try:
return cls._adapter_classes[key] return cls._adapter_classes[key]
except KeyError as e: except KeyError as e:
@ -85,7 +88,7 @@ class DesignateAdapter(object):
format_, object)._render_object(object, *args, **kwargs) format_, object)._render_object(object, *args, **kwargs)
@classmethod @classmethod
def _render_inner_object(cls, object, *args, **kwargs): def _render_object(cls, object, *args, **kwargs):
# The dict we will return to be rendered to JSON / output format # The dict we will return to be rendered to JSON / output format
r_obj = {} r_obj = {}
# Loop over all fields that are supposed to be output # Loop over all fields that are supposed to be output
@ -110,7 +113,7 @@ class DesignateAdapter(object):
r_obj[key] = cls.get_object_adapter( r_obj[key] = cls.get_object_adapter(
cls.ADAPTER_FORMAT, cls.ADAPTER_FORMAT,
object.FIELDS[obj_key].get('relation_cls')).render( object.FIELDS[obj_key].get('relation_cls')).render(
obj, *args, **kwargs) cls.ADAPTER_FORMAT, obj, *args, **kwargs)
else: else:
# Just attach the damn item if there is no weird edge cases # Just attach the damn item if there is no weird edge cases
r_obj[key] = obj r_obj[key] = obj
@ -118,7 +121,7 @@ class DesignateAdapter(object):
return r_obj return r_obj
@classmethod @classmethod
def _render_inner_list(cls, list_object, *args, **kwargs): def _render_list(cls, list_object, *args, **kwargs):
# The list we will return to be rendered to JSON / output format # The list we will return to be rendered to JSON / output format
r_list = [] r_list = []
# iterate and convert each DesignateObject in the list, and append to # iterate and convert each DesignateObject in the list, and append to
@ -126,8 +129,8 @@ class DesignateAdapter(object):
for object in list_object: for object in list_object:
r_list.append(cls.get_object_adapter( r_list.append(cls.get_object_adapter(
cls.ADAPTER_FORMAT, cls.ADAPTER_FORMAT,
object.obj_name()).render(object, *args, **kwargs)) object).render(cls.ADAPTER_FORMAT, object, *args, **kwargs))
return r_list return {cls.MODIFICATIONS['options']['collection_name']: r_list}
##################### #####################
# Parsing methods # # Parsing methods #
@ -140,17 +143,17 @@ class DesignateAdapter(object):
# type_ = 'list' # type_ = 'list'
return cls.get_object_adapter( return cls.get_object_adapter(
format_, format_,
output_object.obj_name())._parse_list( output_object)._parse_list(
values, output_object, *args, **kwargs) values, output_object, *args, **kwargs)
else: else:
# type_ = 'object' # type_ = 'object'
return cls.get_object_adapter( return cls.get_object_adapter(
format_, format_,
output_object.obj_name())._parse_object( output_object)._parse_object(
values, output_object, *args, **kwargs) values, output_object, *args, **kwargs)
@classmethod @classmethod
def _parse_inner_object(cls, values, output_object, *args, **kwargs): def _parse_object(cls, values, output_object, *args, **kwargs):
error_keys = [] error_keys = []
for key, value in values.iteritems(): for key, value in values.iteritems():
@ -163,6 +166,24 @@ class DesignateAdapter(object):
if cls.MODIFICATIONS['fields'][key].get('rename', False): if cls.MODIFICATIONS['fields'][key].get('rename', False):
obj_key = cls.MODIFICATIONS['fields'][key].get('rename') obj_key = cls.MODIFICATIONS['fields'][key].get('rename')
##############################################################
# TODO(graham): Remove this section of code when validation #
# is moved into DesignateObjects properly #
##############################################################
# Check if the field should be allowed change after it is initially
# set (eg domain name)
if cls.MODIFICATIONS['fields'][key].get('idempotent', False):
if getattr(output_object, obj_key, False) and \
getattr(output_object, obj_key) != value:
error_keys.append(key)
break
# Is this field a read only field
elif cls.MODIFICATIONS['fields'][key].get('read_only', True) and \
getattr(output_object, obj_key) != value:
error_keys.append(key)
break
# Check if the key is a nested object # Check if the key is a nested object
if output_object.FIELDS.get(obj_key, {}).get('relation', False): if output_object.FIELDS.get(obj_key, {}).get('relation', False):
# Get the right class name # Get the right class name
@ -196,5 +217,5 @@ class DesignateAdapter(object):
return output_object return output_object
@classmethod @classmethod
def _parse_inner_list(cls, values, output_object, *args, **kwargs): def _parse_list(cls, values, output_object, *args, **kwargs):
raise exceptions.NotImplemented('List adaption not implemented') raise exceptions.NotImplemented('List adaption not implemented')

View File

@ -32,28 +32,11 @@ class DesignateTestAdapter(adapters.DesignateAdapter):
'options': {} 'options': {}
} }
@classmethod
def render(cls, object, *args, **kwargs):
return super(DesignateTestAdapter, cls).render(
cls.ADAPTER_FORMAT, object, *args, **kwargs)
@classmethod
def _render_list(cls, list_object, *args, **kwargs):
inner = cls._render_inner_list(list_object, *args, **kwargs)
return inner
@classmethod
def _render_object(cls, object, *args, **kwargs):
inner = cls._render_inner_object(object, *args, **kwargs)
return inner
class DesignateAdapterTest(tests.TestCase): class DesignateAdapterTest(tests.TestCase):
def test_get_object_adapter(self): def test_get_object_adapter(self):
adapters.DesignateAdapter.get_object_adapter( adapters.DesignateAdapter.get_object_adapter(
'TEST_API', objects.DesignateObject) 'TEST_API', objects.DesignateObject())
def test_get_object_render(self): def test_object_render(self):
adapters.DesignateAdapter.render('TEST_API', objects.DesignateObject) adapters.DesignateAdapter.render('TEST_API', objects.DesignateObject())