Added better schemas for image members, revised tests.

Related to bp glance-api-v2-image-sharing

Change-Id: I01c7fdb78177aaee97f6e7836dea3326b57be33c
This commit is contained in:
Brian Rosmaita 2013-02-28 22:54:37 +00:00
parent 4b705d7ee7
commit a2a4bdd060
5 changed files with 107 additions and 2 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import json
import webob
@ -25,6 +26,7 @@ import glance.domain
import glance.gateway
import glance.notifier
from glance.openstack.common import timeutils
import glance.schema
import glance.store
@ -50,6 +52,7 @@ class ImageMembersController(object):
{'member_id': <MEMBER>,
'image_id': <IMAGE>,
'status': <MEMBER_STATUS>
'created_at': ..,
'updated_at': ..}
@ -82,6 +85,7 @@ class ImageMembersController(object):
{'member_id': <MEMBER>,
'image_id': <IMAGE>,
'status': <MEMBER_STATUS>
'created_at': ..,
'updated_at': ..}
@ -115,6 +119,7 @@ class ImageMembersController(object):
{'members': [
{'member_id': <MEMBER>,
'image_id': <IMAGE>,
'status': <MEMBER_STATUS>
'created_at': ..,
'updated_at': ..}, ..
]}
@ -207,6 +212,7 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
class ResponseSerializer(wsgi.JSONResponseSerializer):
def __init__(self, schema=None):
super(ResponseSerializer, self).__init__()
self.schema = schema or get_schema()
def _format_image_member(self, member):
member_view = {}
@ -215,6 +221,8 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
member_view[key] = getattr(member, key)
member_view['created_at'] = timeutils.isotime(member.created_at)
member_view['updated_at'] = timeutils.isotime(member.updated_at)
member_view['schema'] = '/v2/schemas/member'
member_view = self.schema.filter(member_view)
return member_view
def create(self, response, image_member):
@ -235,11 +243,60 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
for image_member in image_members:
image_member_view = self._format_image_member(image_member)
image_members_view.append(image_member_view)
body = json.dumps(dict(members=image_members_view), ensure_ascii=False)
totalview = dict(members=image_members_view)
totalview['schema'] = '/v2/schemas/members'
body = json.dumps(totalview, ensure_ascii=False)
response.unicode_body = unicode(body)
response.content_type = 'application/json'
_MEMBER_SCHEMA = {
'member_id': {
'type': 'string',
'description': _('An identifier for the image member (tenantId)')
},
'image_id': {
'type': 'string',
'description': _('An identifier for the image'),
'pattern': ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}'
'-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$'),
},
'created_at': {
'type': 'string',
'description': _('Date and time of image member creation'),
#TODO(brian-rosmaita): our jsonschema library doesn't seem to like the
# format attribute, figure out why (and also fix in images.py)
#'format': 'date-time',
},
'updated_at': {
'type': 'string',
'description': _('Date and time of last modification of image member'),
#'format': 'date-time',
},
'status': {
'type': 'string',
'description': _('The status of this image member'),
'enum': [
'pending',
'accepted',
'rejected'
]
},
'schema': {'type': 'string'}
}
def get_schema():
properties = copy.deepcopy(_MEMBER_SCHEMA)
schema = glance.schema.Schema('member', properties)
return schema
def get_collection_schema():
member_schema = get_schema()
return glance.schema.CollectionSchema('members', member_schema)
def create_resource():
"""Image Members resource factory method"""
deserializer = RequestDeserializer()

View File

@ -39,6 +39,14 @@ class API(wsgi.Router):
controller=schemas_resource,
action='images',
conditions={'method': ['GET']})
mapper.connect('/schemas/member',
controller=schemas_resource,
action='member',
conditions={'method': ['GET']})
mapper.connect('/schemas/members',
controller=schemas_resource,
action='members',
conditions={'method': ['GET']})
images_resource = images.create_resource(custom_image_properties)
mapper.connect('/images',

View File

@ -14,6 +14,7 @@
# under the License.
from glance.api.v2 import images
from glance.api.v2 import image_members
from glance.common import wsgi
@ -22,6 +23,8 @@ class Controller(object):
self.image_schema = images.get_schema(custom_image_properties)
self.image_collection_schema = images.get_collection_schema(
custom_image_properties)
self.member_schema = image_members.get_schema()
self.member_collection_schema = image_members.get_collection_schema()
def image(self, req):
return self.image_schema.raw()
@ -29,6 +32,12 @@ class Controller(object):
def images(self, req):
return self.image_collection_schema.raw()
def member(self, req):
return self.member_schema.minimal()
def members(self, req):
return self.member_collection_schema.minimal()
def create_resource(custom_image_properties=None):
controller = Controller(custom_image_properties)

View File

@ -69,6 +69,13 @@ class Schema(object):
raw['links'] = self.links
return raw
def minimal(self):
minimal = {
'name': self.name,
'properties': self.properties
}
return minimal
class PermissiveSchema(Schema):
@staticmethod
@ -80,6 +87,10 @@ class PermissiveSchema(Schema):
raw['additionalProperties'] = {'type': 'string'}
return raw
def minimal(self):
minimal = super(PermissiveSchema, self).raw()
return minimal
class CollectionSchema(object):
@ -105,3 +116,18 @@ class CollectionSchema(object):
{'rel': 'describedby', 'href': '{schema}'},
],
}
def minimal(self):
return {
'name': self.name,
'properties': {
self.name: {
'type': 'array',
'items': self.item_schema.minimal(),
},
'schema': {'type': 'string'},
},
'links': [
{'rel': 'describedby', 'href': '{schema}'},
],
}

View File

@ -294,6 +294,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
'status': 'accepted',
'created_at': ISOTIME,
'updated_at': ISOTIME,
'schema': '/v2/schemas/member',
},
{
'image_id': UUID2,
@ -301,8 +302,10 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
'status': 'pending',
'created_at': ISOTIME,
'updated_at': ISOTIME,
'schema': '/v2/schemas/member',
},
]
],
'schema': '/v2/schemas/members',
}
request = webob.Request.blank('/v2/images/%s/members' % UUID2)
response = webob.Response(request=request)
@ -316,6 +319,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
expected = {'image_id': UUID2,
'member_id': TENANT1,
'status': 'accepted',
'schema': '/v2/schemas/member',
'created_at': ISOTIME,
'updated_at': ISOTIME}
request = webob.Request.blank('/v2/images/%s/members/%s'
@ -331,6 +335,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
expected = {'image_id': UUID2,
'member_id': TENANT1,
'status': 'accepted',
'schema': '/v2/schemas/member',
'created_at': ISOTIME,
'updated_at': ISOTIME}
request = webob.Request.blank('/v2/images/%s/members/%s'