admin.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import hashlib
  2. import logging
  3. from lakesuperior import env
  4. from lakesuperior.config_parser import parse_config
  5. from lakesuperior.dictionaries.namespaces import ns_collection as nsc
  6. from lakesuperior.exceptions import (
  7. ChecksumValidationError, IncompatibleLdpTypeError)
  8. from lakesuperior.migrator import Migrator
  9. from lakesuperior.store.ldp_nr.default_layout import DefaultLayout as FileLayout
  10. __doc__ = """
  11. Admin API.
  12. This module contains maintenance utilities and stats.
  13. """
  14. logger = logging.getLogger(__name__)
  15. def stats():
  16. """
  17. Get repository statistics.
  18. :rtype: dict
  19. :return: Store statistics, resource statistics.
  20. """
  21. import lakesuperior.env_setup
  22. with env.app_globals.rdf_store.txn_ctx():
  23. repo_stats = {'rsrc_stats': env.app_globals.rdfly.count_rsrc()}
  24. repo_stats['store_stats'] = env.app_globals.rdf_store.stats()
  25. return repo_stats
  26. def migrate(src, dest, start_pts=None, list_file=None, **kwargs):
  27. """
  28. Migrate an LDP repository to a new Lakesuperior instance.
  29. See :py:meth:`Migrator.__init__`.
  30. """
  31. if start_pts:
  32. if not isinstance(
  33. start_pts, list) and not isinstance(start_pts, tuple):
  34. start_pts = (start_pts,)
  35. elif not list_file:
  36. start_pts = ('/',)
  37. return Migrator(src, dest, **kwargs).migrate(start_pts, list_file)
  38. def integrity_check():
  39. """
  40. Check integrity of the data set.
  41. At the moment this is limited to referential integrity. Other checks can
  42. be added and triggered by different argument flags.
  43. """
  44. with env.app_globals.rdfly.store.txn_ctx():
  45. return set(env.app_globals.rdfly.find_refint_violations())
  46. def fixity_check(uid):
  47. """
  48. Check fixity of a resource.
  49. This calculates the checksum of a resource and validates it against the
  50. checksum stored in its metadata (``premis:hasMessageDigest``).
  51. :param str uid: UID of the resource to be checked.
  52. :rtype: None
  53. :raises: lakesuperior.exceptions.ChecksumValidationError: the cecksums
  54. do not match. This indicates corruption.
  55. :raises: lakesuperior.exceptions.IncompatibleLdpTypeError: if the
  56. resource is not an LDP-NR.
  57. """
  58. from lakesuperior.api import resource as rsrc_api
  59. from lakesuperior.model.ldp.ldp_factory import LDP_NR_TYPE
  60. rsrc = rsrc_api.get(uid)
  61. with env.app_globals.rdf_store.txn_ctx():
  62. if LDP_NR_TYPE not in rsrc.ldp_types:
  63. raise IncompatibleLdpTypeError()
  64. ref_digest_term = rsrc.metadata.value(nsc['premis'].hasMessageDigest)
  65. ref_digest_parts = ref_digest_term.split(':')
  66. ref_cksum = ref_digest_parts[-1]
  67. ref_cksum_algo = ref_digest_parts[-2]
  68. calc_cksum = hashlib.new(ref_cksum_algo, rsrc.content.read()).hexdigest()
  69. if calc_cksum != ref_cksum:
  70. raise ChecksumValidationError(uid, ref_cksum, calc_cksum)
  71. logger.info(f'Fixity check passed for {uid}.')