Skip to content

Commit 49e3d01

Browse files
committed
CADC-10715 - code review comments - remove CadcDataClient support from the StorageClientWrapper class.
1 parent 4627f24 commit 49e3d01

File tree

3 files changed

+52
-215
lines changed

3 files changed

+52
-215
lines changed

caom2utils/caom2utils/caom2blueprint.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5271,15 +5271,7 @@ def proc(args, obs_blueprints):
52715271
raise RuntimeError(msg)
52725272

52735273
subject = net.Subject.from_cmd_line_args(args)
5274-
if args.resource_id == 'ivo://cadc.nrc.ca/fits2caom2':
5275-
# if the resource_id is the default value, using CadcDataClient
5276-
client = data_util.StorageClientWrapper(
5277-
subject, using_storage_inventory=False)
5278-
else:
5279-
# using the new Storage Inventory system, since it's the one that
5280-
# depends on a resource_id
5281-
client = data_util.StorageClientWrapper(
5282-
subject, resource_id=args.resource_id)
5274+
client = data_util.StorageClientWrapper(subject, resource_id=args.resource_id)
52835275
validate_wcs = True
52845276
if args.no_validate:
52855277
validate_wcs = False

caom2utils/caom2utils/data_util.py

Lines changed: 49 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575

7676
from astropy.io import fits
7777
from urllib.parse import urlparse
78-
from cadcdata import FileInfo, CadcDataClient, StorageInventoryClient
78+
from cadcdata import FileInfo, StorageInventoryClient
7979
from cadcutils import exceptions
8080

8181

@@ -92,61 +92,31 @@
9292

9393
class StorageClientWrapper:
9494
"""
95-
Wrap the choice between CadcDataClient and StorageInventoryClient.
95+
Wrap the metrics collection with StorageInventoryClient.
9696
"""
9797

98-
def __init__(
99-
self,
100-
subject,
101-
using_storage_inventory=True,
102-
resource_id='ivo://cadc.nrc.ca/uvic/minoc',
103-
metrics=None,
104-
):
98+
def __init__(self, subject, resource_id='ivo://cadc.nrc.ca/uvic/minoc', metrics=None):
10599
"""
106-
:param subject: net.Subject instance for authentication and
107-
authorization
108-
:param using_storage_inventory: if True will use
109-
StorageInventoryClient for file operations at CADC. If False will
110-
use CadcDataClient.
111-
:param resource_id: str identifies the StorageInventoryClient
112-
endpoint. If using_storage_inventory is set to False, it's
113-
un-necessary.
114-
:param metrics: caom2pipe.manaage_composable.Metrics instance. If set,
115-
will track execution times, by action, from the beginning of
116-
the method invocation to the end of the method invocation,
117-
success or failure. Defaults to None, because fits2caom2 is
118-
a stand-alone application.
100+
:param subject: net.Subject instance for authentication and authorization
101+
:param resource_id: str identifies the StorageInventoryClient endpoint. Defaults to the installation closest to
102+
most of the current invocations.
103+
:param metrics: caom2pipe.manaage_composable.Metrics instance. If set, will track execution times, by action,
104+
from the beginning of the method invocation to the end of the method invocation, success or failure.
105+
Defaults to None, because fits2caom2 is a stand-alone application.
119106
"""
120-
if using_storage_inventory:
121-
self._cadc_client = StorageInventoryClient(
122-
subject=subject, resource_id=resource_id
123-
)
124-
else:
125-
self._cadc_client = CadcDataClient(subject=subject)
126-
self._use_si = using_storage_inventory
107+
self._cadc_client = StorageInventoryClient(subject=subject, resource_id=resource_id)
127108
self._metrics = metrics
128109
self._logger = logging.getLogger(self.__class__.__name__)
129110

130111
def _add_fail_metric(self, action, name):
131-
"""Single location for the check for a self._metrics member in the
132-
failure case."""
112+
"""Single location for the check for a self._metrics member in the failure case."""
133113
if self._metrics is not None:
134-
client_name = 'si' if self._use_si else 'data'
135-
self._metrics.observe_failure(action, client_name, name)
114+
self._metrics.observe_failure(action, 'si', name)
136115

137116
def _add_metric(self, action, name, start, value):
138-
"""Single location for the check for a self._metrics member in the
139-
success case."""
117+
"""Single location for the check for a self._metrics member in the success case."""
140118
if self._metrics is not None:
141-
client_name = 'si' if self._use_si else 'data'
142-
self._metrics.observe(
143-
start,
144-
StorageClientWrapper._current(),
145-
value,
146-
action,
147-
client_name,
148-
name,
149-
)
119+
self._metrics.observe(start, StorageClientWrapper._current(), value, action, 'si', name)
150120

151121
def get(self, working_directory, uri):
152122
"""
@@ -156,15 +126,12 @@ def get(self, working_directory, uri):
156126
:param uri: str this is an Artifact URI, representing the file to
157127
be retrieved.
158128
"""
159-
self._logger.debug(f'Being get for {uri} in {working_directory}')
129+
self._logger.debug(f'Begin get for {uri} in {working_directory}')
160130
start = StorageClientWrapper._current()
161131
try:
162132
archive, f_name = self._decompose(uri)
163133
fqn = path.join(working_directory, f_name)
164-
if self._use_si:
165-
self._cadc_client.cadcget(uri, dest=fqn)
166-
else:
167-
self._cadc_client.get_file(archive, f_name, destination=fqn)
134+
self._cadc_client.cadcget(uri, dest=fqn)
168135
except Exception as e:
169136
self._add_fail_metric('get', uri)
170137
self._logger.debug(traceback.format_exc())
@@ -186,11 +153,7 @@ def get_head(self, uri):
186153
try:
187154
b = BytesIO()
188155
b.name = uri
189-
if self._use_si:
190-
self._cadc_client.cadcget(uri, b, fhead=True)
191-
else:
192-
archive, f_name = StorageClientWrapper._decompose(uri)
193-
self._cadc_client.get_file(archive, f_name, b, fhead=True)
156+
self._cadc_client.cadcget(uri, b, fhead=True)
194157
fits_header = b.getvalue().decode('ascii')
195158
b.close()
196159
self._add_metric('get_head', uri, start, len(fits_header))
@@ -207,44 +170,28 @@ def get_head(self, uri):
207170

208171
def info(self, uri):
209172
"""
210-
Retrieve the descriptive metdata associated with a file.
173+
Retrieve the descriptive metadata associated with a file.
211174
:param uri: str that is an Artifact URI, representing the file for
212175
which to retrieve metadata
213176
:return: cadcdata.FileInfo instance, no scheme for md5sum
214177
"""
215178
self._logger.debug(f'Begin info for {uri}')
216179
try:
217-
if self._use_si:
218-
result = self._cadc_client.cadcinfo(uri)
219-
# make the result look like the other possible ways to
220-
# obtain metadata
221-
result.md5sum = result.md5sum.replace('md5:', '')
222-
else:
223-
archive, f_name = StorageClientWrapper._decompose(uri)
224-
temp = self._cadc_client.get_file_info(archive, f_name)
225-
result = FileInfo(
226-
id=uri,
227-
size=temp.get('size'),
228-
file_type=temp.get('type'),
229-
md5sum=temp.get('md5sum').replace('md5:', ''),
230-
encoding=temp.get('encoding'),
231-
)
180+
result = self._cadc_client.cadcinfo(uri)
181+
# make the result look like the other possible ways to
182+
# obtain metadata
183+
result.md5sum = result.md5sum.replace('md5:', '')
232184
except exceptions.NotFoundException:
233185
self._logger.info(f'cadcinfo:: {uri} not found')
234186
result = None
235187
self._logger.debug('End info')
236188
return result
237189

238-
def put(self, working_directory, uri, stream='default'):
190+
def put(self, working_directory, uri):
239191
"""
240192
Store a file at CADC.
241-
:param working_directory: str fully-qualified name of where to find
242-
the file on the local machine
243-
:param uri: str that is an Artifact URI, representing the file to
244-
be stored at CADC.
245-
:param stream: str representing the namespace used by the
246-
CadcDataClient. Not required if using the StorageInventoryClient.
247-
'default' is default name for a lately-created ad archive.
193+
:param working_directory: str fully-qualified name of where to find the file on the local machine
194+
:param uri: str that is an Artifact URI, representing the file to be stored at CADC.
248195
"""
249196
self._logger.debug(f'Begin put for {uri} in {working_directory}')
250197
start = self._current()
@@ -255,41 +202,22 @@ def put(self, working_directory, uri, stream='default'):
255202
try:
256203
local_meta = get_local_file_info(fqn)
257204
encoding = get_file_encoding(fqn)
258-
if self._use_si:
259-
replace = True
260-
cadc_meta = self.info(uri)
261-
if cadc_meta is None:
262-
replace = False
263-
self._logger.debug(
264-
f'uri {uri} src {fqn} replace {replace} file_type '
265-
f'{local_meta.file_type} encoding {encoding} md5_checksum '
266-
f'{local_meta.md5sum}'
267-
)
268-
self._cadc_client.cadcput(
269-
uri,
270-
src=fqn,
271-
replace=replace,
272-
file_type=local_meta.file_type,
273-
file_encoding=encoding,
274-
md5_checksum=local_meta.md5sum,
275-
)
276-
else:
277-
archive, f_name = self._decompose(uri)
278-
# libmagic does a worse job with guessing file types
279-
# than ad for .fits.gz => it will say 'binary'
280-
self._logger.debug(
281-
f'archive {archive} f_name {f_name} archive_stream '
282-
f'{stream} mime_type {local_meta.file_type} '
283-
f'mime_encoding {encoding} md5_check True '
284-
)
285-
self._cadc_client.put_file(
286-
archive,
287-
f_name,
288-
archive_stream=stream,
289-
mime_type=local_meta.file_type,
290-
mime_encoding=encoding,
291-
md5_check=True,
292-
)
205+
replace = True
206+
cadc_meta = self.info(uri)
207+
if cadc_meta is None:
208+
replace = False
209+
self._logger.debug(
210+
f'uri {uri} src {fqn} replace {replace} file_type {local_meta.file_type} encoding {encoding} '
211+
f'md5_checksum {local_meta.md5sum}'
212+
)
213+
self._cadc_client.cadcput(
214+
uri,
215+
src=fqn,
216+
replace=replace,
217+
file_type=local_meta.file_type,
218+
file_encoding=encoding,
219+
md5_checksum=local_meta.md5sum,
220+
)
293221
self._logger.info(f'Stored {fqn} at CADC.')
294222
except Exception as e:
295223
self._add_fail_metric('put', uri)
@@ -311,19 +239,14 @@ def remove(self, uri):
311239
"""
312240
self._logger.debug(f'Begin remove for {uri}')
313241
start = StorageClientWrapper._current()
314-
if self._use_si:
315-
try:
316-
self._cadc_client.cadcremove(uri)
317-
except Exception as e:
318-
self._add_fail_metric('remove', uri)
319-
self._logger.debug(traceback.format_exc())
320-
self._logger.error(e)
321-
raise exceptions.UnexpectedException(
322-
f'Did not remove {uri} because {e}'
323-
)
324-
else:
325-
raise NotImplementedError(
326-
'No remove functionality for CadcDataClient'
242+
try:
243+
self._cadc_client.cadcremove(uri)
244+
except Exception as e:
245+
self._add_fail_metric('remove', uri)
246+
self._logger.debug(traceback.format_exc())
247+
self._logger.error(e)
248+
raise exceptions.UnexpectedException(
249+
f'Did not remove {uri} because {e}'
327250
)
328251
self._add_metric('remove', uri, start, value=None)
329252
self._logger.debug('End remove')

caom2utils/caom2utils/tests/test_data_util.py

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -105,77 +105,6 @@ def test_get_file_type():
105105
), f'wrong type {data_util.get_file_type(key)} for {key}'
106106

107107

108-
@patch('caom2utils.data_util.CadcDataClient', autospec=True)
109-
def test_cadc_data_client(cadc_client_mock):
110-
test_subject = Mock(autospec=True)
111-
test_uri = 'ad:TEST/test_file.fits'
112-
test_working_directory = Path(test_fits2caom2.TESTDATA_DIR)
113-
test_fqn = test_working_directory / 'test_file.fits'
114-
if test_fqn.exists():
115-
test_fqn.unlink()
116-
117-
def info_mock(ignore1, ignore2):
118-
return {
119-
'type': 'application/fits',
120-
'md5sum': 'abc',
121-
'size': 42,
122-
}
123-
124-
def get_mock(ignore1, ignore2, destination, **kwargs):
125-
fhead = kwargs.get('fhead')
126-
if fhead:
127-
destination.write(TEST_HEADERS)
128-
else:
129-
test_fqn.write_text('CadcDataClient')
130-
131-
cadc_client_mock.return_value.get_file_info.side_effect = info_mock
132-
cadc_client_mock.return_value.get_file.side_effect = get_mock
133-
cadc_client_mock.return_value.put_file = Mock(autospec=True)
134-
135-
test_wrapper = data_util.StorageClientWrapper(
136-
subject=test_subject,
137-
using_storage_inventory=False,
138-
)
139-
assert test_wrapper is not None, 'ctor failure'
140-
141-
# info
142-
test_result = test_wrapper.info(test_uri)
143-
_check_info_result(test_result)
144-
145-
# get_head
146-
test_result = test_wrapper.get_head(test_uri)
147-
_check_header_result(test_result)
148-
149-
# get
150-
test_wrapper.get(test_working_directory, test_uri)
151-
_check_get_result(test_fqn)
152-
153-
# put
154-
test_wrapper.put(test_working_directory, test_uri)
155-
_check_put_result(cadc_client_mock.return_value.put_file)
156-
157-
# delete
158-
with pytest.raises(NotImplementedError):
159-
test_wrapper.remove(test_uri)
160-
161-
cadc_client_mock.return_value.get_file_info.side_effect = (
162-
exceptions.UnexpectedException('get_file_info')
163-
)
164-
cadc_client_mock.return_value.get_file.side_effect = (
165-
exceptions.UnexpectedException('get_file')
166-
)
167-
cadc_client_mock.return_value.put_file.side_effect = (
168-
exceptions.UnexpectedException('put_file')
169-
)
170-
_fail_mock(test_wrapper, test_uri, test_working_directory)
171-
172-
cadc_client_mock.return_value.get_file_info.side_effect = (
173-
exceptions.NotFoundException('cadcinfo')
174-
)
175-
test_result = test_wrapper.info(test_uri)
176-
assert test_result is None, 'expected when not found'
177-
178-
179108
@patch('caom2utils.data_util.StorageInventoryClient')
180109
def test_storage_inventory_client(cadc_client_mock):
181110
test_subject = Mock(autospec=True)
@@ -201,10 +130,7 @@ def get_si_mock(ignore2, dest, **kwargs):
201130
cadc_client_mock.return_value.cadcput = Mock(autospec=True)
202131
cadc_client_mock.return_value.cadcremove = Mock(autospec=True)
203132

204-
test_wrapper = data_util.StorageClientWrapper(
205-
subject=test_subject,
206-
using_storage_inventory=True,
207-
)
133+
test_wrapper = data_util.StorageClientWrapper(subject=test_subject)
208134
assert test_wrapper is not None, 'ctor failure'
209135

210136
# info
@@ -264,11 +190,7 @@ def _get(working_directory, uri):
264190
client_mock.return_value.cadcget.side_effect = _get
265191
client_mock.return_value.cadcremove.side_effect = Mock()
266192

267-
test_wrapper = data_util.StorageClientWrapper(
268-
subject=test_subject,
269-
using_storage_inventory=True,
270-
metrics=test_metrics,
271-
)
193+
test_wrapper = data_util.StorageClientWrapper(subject=test_subject, metrics=test_metrics)
272194
assert test_wrapper is not None, 'ctor failure'
273195

274196
# test metrics failure

0 commit comments

Comments
 (0)