admin.py 2.9 KB

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