Source code for datacatalog.linkedstores.fixity.store

import inspect
import json
import os
import sys
import time
from pprint import pprint
from datacatalog import settings
from ...dicthelpers import data_merge
from ...identifiers.typeduuid import catalog_uuid
from ...stores import abspath
from ...utils import normalize, normpath
from ..basestore import AgaveClient, LinkedStore, CatalogUpdateFailure, linkages
from ..basestore import HeritableDocumentSchema, JSONSchemaCollection
from ..basestore import RateLimiter, RateLimitExceeded
from .schema import FixityDocument
from .indexer import FixityIndexer
from .exceptions import FixtyUpdateFailure, FixityDuplicateError, FixtyNotFoundError

DEFAULT_LINK_FIELDS = [linkages.CHILD_OF]
# FixityStore is a special case of LinkedStore that creates and manages its
# own records. This is accomplished declaratively using the ``index()`` method.

[docs]class FixityStore(AgaveClient, LinkedStore, RateLimiter): """Defines fixed attributes for a managed file""" LINK_FIELDS = DEFAULT_LINK_FIELDS LOG_JSONDIFF_UPDATES = False def __init__(self, mongodb, agave=None, config={}, session=None, **kwargs): super(FixityStore, self).__init__(mongodb, config, session, agave=agave) # LinkedStore.__init__(self, mongodb, config, session, agave=agave) schema = FixityDocument(**kwargs) super(FixityStore, self).update_attrs(schema) # LinkedStore.update_attrs(self, schema) self.setup(update_indexes=kwargs.get('update_indexes', False)) RateLimiter.__init__(self, **kwargs)
[docs] def index(self, filename, storage_system=None, **kwargs): """Capture or update current properties of a file Fixity includes creation and modification date (rounded to msec), sha256 checksum, size in bytes, and inferred file type. Args: filename (str): Agave-canonical absolute path to the target storage_system (str, optional): Agave storage system for the target Returns: dict: A LinkedStore document containing fixity details """ # print('FIXITY.STORE.INDEX ' + filename) if storage_system is None: storage_system = settings.STORAGE_SYSTEM self.name = normpath(filename) self.abs_filename = self._helper.mapped_posix_path( self.name, storage_system=storage_system) fixity_uuid = self.get_typeduuid(self.name) # Look up the FileStore UUID as it will be used to establish the Fixity # record as its child file_uuid = catalog_uuid(self.name, uuid_type='file') db_record = self.coll.find_one({'uuid': fixity_uuid}) if db_record is None: db_record = {'name': filename, 'storage_system': storage_system, 'uuid': fixity_uuid, 'version': 0, 'child_of': [file_uuid]} # Invoke the RateLimiter that we've mixed in via MultipleInheritance self.limit() indexer = FixityIndexer(schema=self.schema, agave=self._helper.client, **db_record).sync() fixity_record = indexer.to_dict() # lift over private keys to new document for key, value in db_record.items(): if key.startswith('_'): fixity_record[key] = value # Now, update (or init) those same private keys fixity_record = self.set_private_keys(fixity_record, indexer.updated()) resp = self.add_update_document(fixity_record, uuid=fixity_uuid, token=kwargs.get('token', None)) return resp
[docs] def get_typeduuid(self, payload, binary=False): identifier_string = None if isinstance(payload, dict): if 'name' in payload: payload['name'] = normpath(payload['name']) identifier_string = self.get_linearized_values(payload) else: identifier_string = normpath(str(payload)) return super().get_typeduuid(identifier_string, binary)
[docs]class StoreInterface(FixityStore): pass