Merge "Allow to set content-type for uploading blobs"
This commit is contained in:
commit
cfc48043c1
@ -62,21 +62,29 @@ def _chunk_body(body):
|
|||||||
|
|
||||||
|
|
||||||
def _set_request_params(kwargs_params):
|
def _set_request_params(kwargs_params):
|
||||||
|
"""Handle the common parameters used to send the request."""
|
||||||
|
|
||||||
data = kwargs_params.pop('data', None)
|
data = kwargs_params.pop('data', None)
|
||||||
params = copy.deepcopy(kwargs_params)
|
params = copy.deepcopy(kwargs_params)
|
||||||
headers = params.get('headers', {})
|
headers = params.get('headers', {})
|
||||||
content_type = headers.get('Content-Type', 'application/json')
|
content_type = headers.get('Content-Type')
|
||||||
|
stream = params.get("stream", False)
|
||||||
|
|
||||||
if data is not None and not isinstance(data, six.string_types):
|
if stream:
|
||||||
if content_type.startswith('application/json'):
|
if data is not None:
|
||||||
data = jsonutils.dumps(data)
|
|
||||||
if content_type == 'application/octet-stream':
|
|
||||||
data = _chunk_body(data)
|
data = _chunk_body(data)
|
||||||
|
content_type = content_type or 'application/octet-stream'
|
||||||
|
elif data is not None and not isinstance(data, six.string_types):
|
||||||
|
try:
|
||||||
|
data = jsonutils.dumps(data)
|
||||||
|
except TypeError:
|
||||||
|
raise exc.HTTPBadRequest("json is malformed.")
|
||||||
|
|
||||||
params['data'] = data
|
params['data'] = data
|
||||||
headers.update({'Content-Type': content_type})
|
headers.update(
|
||||||
|
{'Content-Type': content_type or 'application/json'})
|
||||||
params['headers'] = headers
|
params['headers'] = headers
|
||||||
params['stream'] = content_type == 'application/octet-stream'
|
params['stream'] = stream
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
@ -62,6 +62,12 @@ class UploadBlob(command.ShowOne):
|
|||||||
metavar='<BLOB_PROPERTY>',
|
metavar='<BLOB_PROPERTY>',
|
||||||
help='Name of the blob field.'
|
help='Name of the blob field.'
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--content-type',
|
||||||
|
metavar='<CONTENT_TYPE>',
|
||||||
|
default='application/octet-stream',
|
||||||
|
help='Content-type of the blob.'
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--progress',
|
'--progress',
|
||||||
help='Show download progress bar.'
|
help='Show download progress bar.'
|
||||||
@ -83,8 +89,8 @@ class UploadBlob(command.ShowOne):
|
|||||||
blob = progressbar.VerboseFileWrapper(blob, file_size)
|
blob = progressbar.VerboseFileWrapper(blob, file_size)
|
||||||
|
|
||||||
client.artifacts.upload_blob(parsed_args.id,
|
client.artifacts.upload_blob(parsed_args.id,
|
||||||
parsed_args.blob_property,
|
parsed_args.blob_property, blob,
|
||||||
blob,
|
content_type=parsed_args.content_type,
|
||||||
type_name=parsed_args.type_name)
|
type_name=parsed_args.type_name)
|
||||||
|
|
||||||
data = client.artifacts.get(parsed_args.id,
|
data = client.artifacts.get(parsed_args.id,
|
||||||
|
@ -135,6 +135,38 @@ class TestUploadBlob(TestBlobs):
|
|||||||
with testtools.ExpectedException(SystemExit):
|
with testtools.ExpectedException(SystemExit):
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
def test_upload_with_custom_content_type(self):
|
||||||
|
exp_data = ('template', 'application/x-yaml', False,
|
||||||
|
'35d83e8eedfbdb87ff97d1f2761f8ebf',
|
||||||
|
'942854360eeec1335537702399c5aed940401602',
|
||||||
|
'd8a7834fc6652f316322d80196f6dcf2'
|
||||||
|
'94417030e37c15412e4deb7a67a367dd',
|
||||||
|
594, 'active', 'fake_url')
|
||||||
|
|
||||||
|
mocked_get = {
|
||||||
|
"status": "active",
|
||||||
|
"url": "fake_url",
|
||||||
|
"md5": "35d83e8eedfbdb87ff97d1f2761f8ebf",
|
||||||
|
"sha1": "942854360eeec1335537702399c5aed940401602",
|
||||||
|
"sha256": "d8a7834fc6652f316322d80196f6dcf2"
|
||||||
|
"94417030e37c15412e4deb7a67a367dd",
|
||||||
|
"external": False,
|
||||||
|
"content_type": "application/x-yaml",
|
||||||
|
"size": 594}
|
||||||
|
self.app.client_manager.artifact.artifacts.get = \
|
||||||
|
lambda id, type_name: {'template': mocked_get}
|
||||||
|
|
||||||
|
arglist = ['tosca_templates',
|
||||||
|
'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba',
|
||||||
|
'--file', '/path/to/file',
|
||||||
|
'--content-type', 'application/x-yaml']
|
||||||
|
verify = [('type_name', 'tosca_templates')]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verify)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
self.assertEqual(self.COLUMNS, columns)
|
||||||
|
self.assertEqual(exp_data, data)
|
||||||
|
|
||||||
def test_upload_blob_with_blob_prop(self):
|
def test_upload_blob_with_blob_prop(self):
|
||||||
exp_data = ('blob', 'application/octet-stream', False,
|
exp_data = ('blob', 'application/octet-stream', False,
|
||||||
'35d83e8eedfbdb87ff97d1f2761f8ebf',
|
'35d83e8eedfbdb87ff97d1f2761f8ebf',
|
||||||
|
@ -306,6 +306,23 @@ class TestController(testtools.TestCase):
|
|||||||
'data')]
|
'data')]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
|
|
||||||
|
def test_upload_blob_custom_content_type(self):
|
||||||
|
art_id = '3a4560a1-e585-443e-9b39-553b46ec92a3'
|
||||||
|
self.controller.upload_blob(artifact_id=art_id,
|
||||||
|
type_name='sample_artifact',
|
||||||
|
blob_property='blob',
|
||||||
|
data='{"a":"b"}',
|
||||||
|
content_type='application/json',)
|
||||||
|
|
||||||
|
exp_headers = {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
|
||||||
|
expect = [('PUT', '/artifacts/sample_artifact/%s/blob' % art_id,
|
||||||
|
exp_headers,
|
||||||
|
{"a": "b"})]
|
||||||
|
self.assertEqual(expect, self.api.calls)
|
||||||
|
|
||||||
def test_download_blob(self):
|
def test_download_blob(self):
|
||||||
art_id = '3a4560a1-e585-443e-9b39-553b46ec92a3'
|
art_id = '3a4560a1-e585-443e-9b39-553b46ec92a3'
|
||||||
self.controller.download_blob(artifact_id=art_id,
|
self.controller.download_blob(artifact_id=art_id,
|
||||||
|
@ -26,7 +26,7 @@ class FakeAPI(object):
|
|||||||
self.calls = []
|
self.calls = []
|
||||||
|
|
||||||
def _request(self, method, url, headers=None, data=None,
|
def _request(self, method, url, headers=None, data=None,
|
||||||
content_length=None):
|
content_length=None, **kwargs):
|
||||||
call = build_call_record(method, sort_url_by_query_keys(url),
|
call = build_call_record(method, sort_url_by_query_keys(url),
|
||||||
headers or {}, data)
|
headers or {}, data)
|
||||||
if content_length is not None:
|
if content_length is not None:
|
||||||
@ -210,5 +210,4 @@ def build_call_record(method, url, headers, data):
|
|||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return (method, url, headers or {}, data)
|
return (method, url, headers or {}, data)
|
||||||
data = [sorted(d.items()) for d in data]
|
|
||||||
return (method, url, headers or {}, data)
|
return (method, url, headers or {}, data)
|
||||||
|
@ -202,16 +202,18 @@ class Controller(object):
|
|||||||
url = '/artifacts/%s/%s' % (type_name, artifact_id)
|
url = '/artifacts/%s/%s' % (type_name, artifact_id)
|
||||||
self.http_client.delete(url)
|
self.http_client.delete(url)
|
||||||
|
|
||||||
def upload_blob(self, artifact_id, blob_property, data, type_name=None):
|
def upload_blob(self, artifact_id, blob_property, data, type_name=None,
|
||||||
|
content_type=None):
|
||||||
"""Upload blob data.
|
"""Upload blob data.
|
||||||
|
|
||||||
:param artifact_id: ID of the artifact to download a blob
|
:param artifact_id: ID of the artifact to download a blob
|
||||||
:param blob_property: blob property name
|
:param blob_property: blob property name
|
||||||
"""
|
"""
|
||||||
|
content_type = content_type or 'application/octet-stream'
|
||||||
type_name = self._check_type_name(type_name)
|
type_name = self._check_type_name(type_name)
|
||||||
hdrs = {'Content-Type': 'application/octet-stream'}
|
hdrs = {'Content-Type': content_type}
|
||||||
url = '/artifacts/%s/%s/%s' % (type_name, artifact_id, blob_property)
|
url = '/artifacts/%s/%s/%s' % (type_name, artifact_id, blob_property)
|
||||||
self.http_client.put(url, headers=hdrs, data=data)
|
self.http_client.put(url, headers=hdrs, data=data, stream=True)
|
||||||
|
|
||||||
def download_blob(self, artifact_id, blob_property, type_name=None,
|
def download_blob(self, artifact_id, blob_property, type_name=None,
|
||||||
do_checksum=True):
|
do_checksum=True):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user