Merge "Wrap image data in iterator"

This commit is contained in:
Jenkins
2012-07-19 20:19:30 +00:00
committed by Gerrit Code Review
3 changed files with 34 additions and 6 deletions

View File

@@ -5,6 +5,7 @@ OpenStack Client interface. Handles the REST calls and responses.
import copy import copy
import logging import logging
import os import os
import StringIO
import urlparse import urlparse
import httplib2 import httplib2
@@ -25,6 +26,7 @@ from glanceclient import exc
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
USER_AGENT = 'python-glanceclient' USER_AGENT = 'python-glanceclient'
CHUNKSIZE = 1024 * 64 # 64kB
class HTTPClient(httplib2.Http): class HTTPClient(httplib2.Http):
@@ -88,7 +90,12 @@ class HTTPClient(httplib2.Http):
# Redirected. Reissue the request to the new location. # Redirected. Reissue the request to the new location.
return self._http_request(resp['location'], method, **kwargs) return self._http_request(resp['location'], method, **kwargs)
return resp, body #NOTE(bcwaldon): body has been loaded to a string at this point,
# but we want to move to a world where it can be read from a
# socket-level cache. This is here until we can do that.
body_iter = ResponseBodyIterator(StringIO.StringIO(body))
return resp, body_iter
def json_request(self, method, url, **kwargs): def json_request(self, method, url, **kwargs):
kwargs.setdefault('headers', {}) kwargs.setdefault('headers', {})
@@ -97,7 +104,8 @@ class HTTPClient(httplib2.Http):
if 'body' in kwargs: if 'body' in kwargs:
kwargs['body'] = json.dumps(kwargs['body']) kwargs['body'] = json.dumps(kwargs['body'])
resp, body = self._http_request(url, method, **kwargs) resp, body_iter = self._http_request(url, method, **kwargs)
body = ''.join([chunk for chunk in body_iter])
if body: if body:
try: try:
@@ -115,3 +123,21 @@ class HTTPClient(httplib2.Http):
kwargs['headers'].setdefault('Content-Type', kwargs['headers'].setdefault('Content-Type',
'application/octet-stream') 'application/octet-stream')
return self._http_request(url, method, **kwargs) return self._http_request(url, method, **kwargs)
class ResponseBodyIterator(object):
"""A class that acts as an iterator over an HTTP response."""
def __init__(self, resp):
self.resp = resp
def __iter__(self):
while True:
yield self.next()
def next(self):
chunk = self.resp.read(CHUNKSIZE)
if chunk:
return chunk
else:
raise StopIteration()

View File

@@ -159,8 +159,9 @@ class ImageManager(base.Manager):
if copy_from is not None: if copy_from is not None:
hdrs['x-glance-api-copy-from'] = copy_from hdrs['x-glance-api-copy-from'] = copy_from
resp, body = self.api.raw_request( resp, body_iter = self.api.raw_request(
'POST', '/v1/images', headers=hdrs, body=image_data) 'POST', '/v1/images', headers=hdrs, body=image_data)
body = ''.join([c for c in body_iter])
return Image(self, json.loads(body)['image']) return Image(self, json.loads(body)['image'])
def update(self, image, **kwargs): def update(self, image, **kwargs):
@@ -199,6 +200,7 @@ class ImageManager(base.Manager):
hdrs['x-glance-api-copy-from'] = copy_from hdrs['x-glance-api-copy-from'] = copy_from
url = '/v1/images/%s' % base.getid(image) url = '/v1/images/%s' % base.getid(image)
resp, body = self.api.raw_request( resp, body_iter = self.api.raw_request(
'PUT', url, headers=hdrs, body=image_data) 'PUT', url, headers=hdrs, body=image_data)
body = ''.join([c for c in body_iter])
return Image(self, json.loads(body)['image']) return Image(self, json.loads(body)['image'])

View File

@@ -131,7 +131,7 @@ class ImageManagerTest(unittest.TestCase):
self.assertEqual(image.name, 'image-1') self.assertEqual(image.name, 'image-1')
def test_data(self): def test_data(self):
data = self.mgr.data('1') data = ''.join([b for b in self.mgr.data('1')])
expect = [('GET', '/v1/images/1', {}, None)] expect = [('GET', '/v1/images/1', {}, None)]
self.assertEqual(self.api.calls, expect) self.assertEqual(self.api.calls, expect)
self.assertEqual(data, 'XXX') self.assertEqual(data, 'XXX')
@@ -256,7 +256,7 @@ class ImageTest(unittest.TestCase):
def test_data(self): def test_data(self):
image = self.mgr.get('1') image = self.mgr.get('1')
data = image.data() data = ''.join([b for b in image.data()])
expect = [ expect = [
('HEAD', '/v1/images/1', {}, None), ('HEAD', '/v1/images/1', {}, None),
('GET', '/v1/images/1', {}, None), ('GET', '/v1/images/1', {}, None),