From d0eb05ee0327ac4e21ad6c989265d3a618d4b1f2 Mon Sep 17 00:00:00 2001 From: Marina Golosova Date: Wed, 10 Jul 2019 16:31:17 +0200 Subject: [PATCH] pyDKB/storages: implement `RucioClient.get()` method. Original Rucio `Client` does not have `get()` method. --- Utils/Dataflow/pyDKB/storages/atlas/rucio.py | 60 +++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Utils/Dataflow/pyDKB/storages/atlas/rucio.py b/Utils/Dataflow/pyDKB/storages/atlas/rucio.py index 58da402fc..ab7632ab0 100644 --- a/Utils/Dataflow/pyDKB/storages/atlas/rucio.py +++ b/Utils/Dataflow/pyDKB/storages/atlas/rucio.py @@ -5,7 +5,7 @@ import os from ..client import Client -from ..exceptions import StorageException +from ..exceptions import (StorageException, NotFound) from pyDKB.common.misc import (log, logLevel) from pyDKB.common.misc import try_to_import @@ -50,3 +50,61 @@ class RucioClient(Client, ParentClientClass): def __init__(self, *args, **kwargs): """ Initialize parent client class. """ ParentClientClass.__init__(self, *args, **kwargs) + + def get(self, oid, **kwargs): + """ Get dataset metadata. + + Implementation of interface method `Clent.get()`. + + :param oid: dataset name + :type oid: str + :param fields: list of requested metadata fields + (None = all metadata) + :type fields: list + + :return: dataset metadata + :rtype: dict + """ + scope, name = self._scope_and_name(oid) + try: + result = self.get_metadata(scope=scope, name=name) + except ValueError, err: + raise StorageException("Failed to get metadata from Rucio: %s" + % err) + except RucioException, err: + if 'Data identifier not found' in str(err): + raise NotFound(scope=scope, name=name) + raise StorageException("Failed to get metadata from Rucio: %s" + % err) + if kwargs.get('fields') is not None: + result = {f: result.get(f, None) for f in kwargs['fields']} + return result + + def _scope_and_name(self, dsn): + """ Construct normalized scope and dataset name. + + As input accepts dataset names in two forms: + * dot-separated string: ".[.<...>]"; + * dot-separated string with prefix: ":.[.<...>]". + + In first case ID is taken as a canonical dataset name and scope is set + to its first field (or two first fields, if the ID starts with 'user' + or 'group'). + In second case prefix is taken as scope, and removed from ID to get the + canonical dataset name. + + :param dsn: dataset name + :type dsn: str + + :return: scope, datasetname + :rtype: tuple + """ + result = dsn.split(':') + if len(result) < 2: + splitted = dsn.split('.') + if dsn.startswith('user') or dsn.startswith('group'): + scope = '.'.join(splitted[0:2]) + else: + scope = splitted[0] + result = (scope, dsn) + return result