Add glare type names in json-schema output

Change-Id: Ic1bfb876f1d93a929c67724dcac2195effaf8f97
This commit is contained in:
Mike Fedosin 2016-09-29 18:05:05 +03:00
parent e0f63c887e
commit e6d7af4cf8
6 changed files with 130 additions and 32 deletions

View File

@ -40,11 +40,13 @@ from oslo_log import log as logging
from oslo_utils import encodeutils
from oslo_utils import excutils
from oslo_utils import timeutils
from oslo_versionedobjects import fields
import six
from webob import exc
from glare.common import exception
from glare.i18n import _, _LE, _LW
from glare.objects.meta import fields as glare_fields
CONF = cfg.CONF
@ -553,6 +555,54 @@ class error_handler(object):
return new_function
def get_schema_type(attr):
if isinstance(attr, fields.IntegerField):
return 'integer'
elif isinstance(attr, fields.FloatField):
return 'number'
elif isinstance(attr, fields.BooleanField):
return 'boolean'
elif isinstance(attr, glare_fields.List):
return 'array'
elif isinstance(attr, (glare_fields.Dict, glare_fields.BlobField)):
return 'object'
return 'string'
def get_glare_type(attr):
if isinstance(attr, fields.IntegerField):
return 'Integer'
elif isinstance(attr, fields.FloatField):
return 'Float'
elif isinstance(attr, fields.FlexibleBooleanField):
return 'Boolean'
elif isinstance(attr, fields.DateTimeField):
return 'DateTime'
elif isinstance(attr, glare_fields.BlobField):
return 'Blob'
elif isinstance(attr, glare_fields.Link):
return 'Link'
elif isinstance(attr, glare_fields.List):
return _get_element_type(attr.element_type) + 'List'
elif isinstance(attr, glare_fields.Dict):
return _get_element_type(attr.element_type) + 'Dict'
return 'String'
def _get_element_type(element_type):
if element_type is fields.FlexibleBooleanField:
return 'Boolean'
elif element_type is fields.Integer:
return 'Integer'
elif element_type is fields.Float:
return 'Float'
elif element_type is glare_fields.BlobFieldType:
return 'Blob'
elif element_type is glare_fields.LinkFieldType:
return 'Link'
return 'String'
class DictDiffer(object):
"""
Calculate the difference between two dictionaries as:

View File

@ -1087,23 +1087,9 @@ class BaseArtifact(base.VersionedObject):
res[key] = val
return res
@staticmethod
def schema_type(attr):
if isinstance(attr, fields.IntegerField):
return 'integer'
elif isinstance(attr, fields.FloatField):
return 'number'
elif isinstance(attr, fields.BooleanField):
return 'boolean'
elif isinstance(attr, glare_fields.List):
return 'array'
elif isinstance(attr, (glare_fields.Dict, glare_fields.BlobField)):
return 'object'
return 'string'
@classmethod
def schema_attr(cls, attr, attr_name=''):
attr_type = cls.schema_type(attr)
attr_type = utils.get_schema_type(attr)
schema = {}
# generate schema for validators
@ -1112,6 +1098,7 @@ class BaseArtifact(base.VersionedObject):
schema['type'] = (attr_type
if not attr.nullable else [attr_type, 'null'])
schema['glareType'] = utils.get_glare_type(attr)
output_blob_schema = {
'type': ['object', 'null'],
'properties': {
@ -1134,7 +1121,7 @@ class BaseArtifact(base.VersionedObject):
schema['readOnly'] = True
if isinstance(attr, glare_fields.Dict):
element_type = (cls.schema_type(attr.element_type)
element_type = (utils.get_schema_type(attr.element_type)
if hasattr(attr, 'element_type')
else 'string')
@ -1156,7 +1143,7 @@ class BaseArtifact(base.VersionedObject):
if attr_type == 'array':
schema['items'] = {
'type': (cls.schema_type(attr.element_type)
'type': (utils.get_schema_type(attr.element_type)
if hasattr(attr, 'element_type')
else 'string')}

View File

@ -29,7 +29,7 @@ BlobDict = attribute.BlobDictAttribute.init
class HeatTemplate(base.BaseArtifact):
fields = {
'environments': Dict(glare_fields.Link,
'environments': Dict(glare_fields.LinkFieldType,
mutable=True,
description="References to Heat Environments "
"that can be used with current "

View File

@ -50,7 +50,7 @@ class MuranoPackage(base.BaseArtifact):
"the package."),
'inherits': Dict(fields.String),
'keywords': List(fields.String, mutable=True),
'dependencies': List(glare_fields.Link,
'dependencies': List(glare_fields.LinkFieldType,
required_on_activate=False,
description="List of package dependencies for "
"this package."),

View File

@ -27,7 +27,7 @@ def sort_results(lst, target='name'):
class TestArtifact(functional.FunctionalTest):
enabled_types = (u'sample_artifact', u'images', u'heat_templates',
u'heat_environments', u'tosca_templates',
u'murano_packages')
u'murano_packages', u'all')
users = {
'user1': {

View File

@ -29,6 +29,7 @@ fixture_base_props = {
u'lt',
u'lte'],
u'format': u'date-time',
u'glareType': u'DateTime',
u'readOnly': True,
u'required_on_activate': False,
u'sortable': True,
@ -44,6 +45,7 @@ fixture_base_props = {
u'lt',
u'lte'],
u'format': u'date-time',
u'glareType': u'DateTime',
u'readOnly': True,
u'sortable': True,
u'type': u'string'},
@ -52,6 +54,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 4096,
u'mutable': True,
u'required_on_activate': False,
@ -60,6 +63,7 @@ fixture_base_props = {
u'icon': {u'additionalProperties': False,
u'description': u'Artifact icon.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
u'sha256': {u'type': [u'string', u'null']},
@ -83,6 +87,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'pattern': u'^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}'
u'-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$',
@ -93,6 +98,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string',
@ -101,6 +107,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string',
@ -111,6 +118,7 @@ fixture_base_props = {
u'about an artifact.',
u'filter_ops': [u'eq',
u'neq'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'required_on_activate': False,
u'type': [u'object',
@ -119,6 +127,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'sortable': True,
@ -127,6 +136,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'readOnly': True,
u'required_on_activate': False,
@ -137,6 +147,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'properties': {u'company': {u'type': u'string'},
u'href': {u'type': u'string'},
@ -151,6 +162,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'required_on_activate': False,
@ -166,6 +178,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'sortable': True,
u'type': u'string'},
u'supported_by': {u'additionalProperties': {u'type': u'string'},
@ -174,6 +187,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'required': [u'name'],
u'required_on_activate': False,
@ -184,6 +198,7 @@ fixture_base_props = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'mutable': True,
@ -200,6 +215,7 @@ fixture_base_props = {
u'lt',
u'lte'],
u'format': u'date-time',
u'glareType': u'DateTime',
u'readOnly': True,
u'sortable': True,
u'type': u'string'},
@ -212,6 +228,7 @@ fixture_base_props = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'String',
u'pattern': u'/^([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-'
u'([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?'
u'(?:\\+[0-9A-Za-z-]+)?$/',
@ -223,6 +240,7 @@ fixture_base_props = {
u'artifact can be available to other '
u'users.',
u'filter_ops': [u'eq'],
u'glareType': u'String',
u'maxLength': 255,
u'sortable': True,
u'type': u'string'}
@ -241,6 +259,7 @@ fixtures = {
u'blob': {u'additionalProperties': False,
u'description': u'I am Blob',
u'filter_ops': [],
u'glareType': u'Blob',
u'mutable': True,
u'properties': {
u'md5': {u'type': [u'string', u'null']},
@ -269,23 +288,27 @@ fixtures = {
u'null']},
u'bool1': {u'default': False,
u'filter_ops': [u'eq'],
u'glareType': u'Boolean',
u'required_on_activate': False,
u'type': [u'string',
u'null']},
u'bool2': {u'default': False,
u'filter_ops': [u'eq'],
u'glareType': u'Boolean',
u'required_on_activate': False,
u'type': [u'string',
u'null']},
u'link1': {u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'Link',
u'required_on_activate': False,
u'type': [u'string',
u'null']},
u'link2': {u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'Link',
u'required_on_activate': False,
u'type': [u'string',
u'null']},
@ -319,6 +342,7 @@ fixtures = {
u'null']},
u'default': {},
u'filter_ops': [],
u'glareType': u'BlobDict',
u'maxProperties': 255,
u'required_on_activate': False,
u'type': [u'object',
@ -328,6 +352,7 @@ fixtures = {
u'type': u'string'},
u'default': {},
u'filter_ops': [u'eq'],
u'glareType': u'IntegerDict',
u'maxProperties': 255,
u'required_on_activate': False,
u'type': [u'object',
@ -337,6 +362,7 @@ fixtures = {
u'type': u'string'},
u'default': {},
u'filter_ops': [u'eq'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'required_on_activate': False,
u'type': [u'object',
@ -346,6 +372,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringDict',
u'maxProperties': 3,
u'properties': {
u'abc': {u'type': [u'string',
@ -366,6 +393,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'Float',
u'required_on_activate': False,
u'sortable': True,
u'type': [u'number',
@ -377,6 +405,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'Float',
u'required_on_activate': False,
u'sortable': True,
u'type': [u'number',
@ -388,6 +417,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'Integer',
u'required_on_activate': False,
u'sortable': True,
u'type': [u'integer',
@ -399,6 +429,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'Integer',
u'required_on_activate': False,
u'sortable': True,
u'type': [u'integer',
@ -410,6 +441,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'Integer',
u'maximum': 20,
u'minimum': 10,
u'required_on_activate': False,
@ -417,6 +449,7 @@ fixtures = {
u'null']},
u'list_of_int': {u'default': [],
u'filter_ops': [u'eq'],
u'glareType': u'IntegerList',
u'items': {
u'type': u'string'},
u'maxItems': 255,
@ -425,6 +458,7 @@ fixtures = {
u'null']},
u'list_of_str': {u'default': [],
u'filter_ops': [u'eq'],
u'glareType': u'StringList',
u'items': {
u'type': u'string'},
u'maxItems': 255,
@ -436,6 +470,7 @@ fixtures = {
u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {
u'type': u'string'},
u'maxItems': 3,
@ -445,6 +480,7 @@ fixtures = {
u'unique': True},
u'small_blob': {u'additionalProperties': False,
u'filter_ops': [],
u'glareType': u'Blob',
u'mutable': True,
u'properties': {
u'md5': {u'type': [u'string', u'null']},
@ -479,6 +515,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'sortable': True,
@ -491,6 +528,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'String',
u'maxLength': 255,
u'mutable': True,
u'required_on_activate': False,
@ -504,6 +542,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string',
u'null']},
@ -519,6 +558,7 @@ fixtures = {
u'gte',
u'lt',
u'lte'],
u'glareType': u'String',
u'maxLength': 10,
u'required_on_activate': False,
u'type': [u'string',
@ -527,6 +567,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'readOnly': True,
u'sortable': True,
@ -544,6 +585,7 @@ fixtures = {
u'additionalProperties': False,
u'description': u'TOSCA template body.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {
u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
@ -568,6 +610,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string',
u'null']},
@ -586,6 +629,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'mutable': True,
@ -598,6 +642,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'type': [u'array',
@ -610,6 +655,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'LinkList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'required_on_activate': False,
@ -620,6 +666,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'mutable': True,
u'type': [u'string',
@ -630,6 +677,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'type': [u'object',
u'null']},
@ -637,6 +685,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringList',
u'items': {u'type': u'string'},
u'maxItems': 255,
u'mutable': True,
@ -646,6 +695,7 @@ fixtures = {
u'additionalProperties': False,
u'description': u'Murano Package binary.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
u'sha256': {u'type': [u'string', u'null']},
@ -674,6 +724,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string',
u'null']}
@ -693,6 +744,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string',
@ -701,6 +753,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string', u'null']},
@ -716,6 +769,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string',
u'null']},
@ -735,11 +789,13 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string', u'null']},
u'image': {u'additionalProperties': False,
u'description': u'Image binary.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {
u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
@ -769,6 +825,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string', u'null']},
@ -780,6 +837,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string',
@ -791,6 +849,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'pattern': u'^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-'
u'([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-'
@ -802,6 +861,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'Integer',
u'minimum': 0,
u'required_on_activate': False,
u'type': [u'integer', u'null']},
@ -810,6 +870,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'Integer',
u'minimum': 0,
u'required_on_activate': False,
u'type': [u'integer', u'null']},
@ -821,6 +882,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string', u'null']},
@ -830,6 +892,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'required_on_activate': False,
u'type': [u'string', u'null']},
@ -840,6 +903,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'pattern': u'^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F])'
u'{4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$',
@ -861,6 +925,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'StringDict',
u'maxProperties': 255,
u'mutable': True,
u'type': [u'object',
@ -874,6 +939,7 @@ fixtures = {
u'filter_ops': [u'eq',
u'neq',
u'in'],
u'glareType': u'LinkDict',
u'maxProperties': 255,
u'mutable': True,
u'type': [u'object',
@ -906,6 +972,7 @@ fixtures = {
u'name of template and value is nested '
u'template body.',
u'filter_ops': [],
u'glareType': u'BlobDict',
u'maxProperties': 255,
u'type': [u'object',
u'null']},
@ -913,6 +980,7 @@ fixtures = {
u'additionalProperties': False,
u'description': u'Heat template body.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {
u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
@ -946,6 +1014,7 @@ fixtures = {
u'additionalProperties': False,
u'description': u'Heat Environment text body.',
u'filter_ops': [],
u'glareType': u'Blob',
u'properties': {u'md5': {u'type': [u'string', u'null']},
u'sha1': {u'type': [u'string', u'null']},
u'sha256': {u'type': [u'string', u'null']},
@ -975,6 +1044,7 @@ fixtures = {
u'properties': generate_type_props({
u'type_name': {u'description': u'Name of artifact type.',
u'filter_ops': [u'eq', u'neq', u'in'],
u'glareType': u'String',
u'maxLength': 255,
u'type': [u'string', u'null']},
@ -993,22 +1063,13 @@ class TestSchemas(base.TestArtifact):
result = self.get(url='/schemas/%s' % at)
self.assertEqual(fixtures[at], result['schemas'][at],
utils.DictDiffer(
result['schemas'][at]['properties'],
fixtures[at]['properties']))
fixtures[at]['properties'],
result['schemas'][at]['properties']))
# Get list schemas of artifacts
result = self.get(url='/schemas')
self.assertEqual(fixtures, result['schemas'], utils.DictDiffer(
result['schemas'], fixtures))
# Get schema of sample_artifact
result = self.get(url='/schemas/sample_artifact')
self.assertEqual(fixtures['sample_artifact'],
result['schemas']['sample_artifact'],
utils.DictDiffer(
result['schemas']['sample_artifact'][
'properties'],
fixtures['sample_artifact']['properties']))
fixtures, result['schemas']))
# Validation of schemas
result = self.get(url='/schemas')['schemas']