quoideneuf / aspace-noid

NOIDs for ArchivesSpace

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NOIDs for ArchivesSpace

This plugin is experimental. Use at your own risk.

This plugin enables NOIDs (Nice Opaque Identifiers) for ArchivesSpace building on the ARK generalization work that will be available in ArchivesSpace 3.2.0 (see #2472). For more info on NOIDs see the documentation of the noid tool.

Internally the noid gem is used to do the heavy lifting. To use it put it into the list of your plugins and change the ark_minter setting in your configuration file to

AppConfig[:ark_minter] = :noid_ark_minter

The plugin adds a field "ARK Template" to repositories where you can specify a noid template. The template is then used to create a minter per repository. The state of each minter is persisted in the database in the new ark_minter table.

Currently this plugin ignores the ark_shoulder_delimiter setting because NOIDs do not seem to separate shoulder and blade.

ArchivesSpace patch required

To use this plugin you currently will have to patch your ArchivesSpace code because it requires an extension to the ArkMinter interface:

From eff0570ad0f4591dd07117f800f4336c99d361dc Mon Sep 17 00:00:00 2001
From: me <some@email.org>
Date: Sun, 16 Jan 2022 21:22:53 +0100
Subject: [PATCH 1/1] add obj to ark_recognized? to be able to pass repo_id

---
 backend/app/lib/ark/archivesspace_ark_minter.rb | 2 +-
 backend/app/lib/ark/ark_minter.rb               | 5 +++--
 backend/app/lib/ark/smithsonian_ark_minter.rb   | 2 +-
 backend/app/model/ark_name.rb                   | 4 ++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/backend/app/lib/ark/archivesspace_ark_minter.rb b/backend/app/lib/ark/archivesspace_ark_minter.rb
index 451e47278..11908408a 100644
--- a/backend/app/lib/ark/archivesspace_ark_minter.rb
+++ b/backend/app/lib/ark/archivesspace_ark_minter.rb
@@ -16,7 +16,7 @@ class ArchivesSpaceArkMinter < ArkMinter
 
   # True if the ARK has the right NAAN and has a number that falls within the
   # range that we have already minted.
-  def ark_recognized?(ark)
+  def ark_recognized?(ark, obj)
     if ark =~ %r{/ark:/#{AppConfig[:ark_naan]}/.*?(\d+)$}
       ark_number = Integer($1)
 
diff --git a/backend/app/lib/ark/ark_minter.rb b/backend/app/lib/ark/ark_minter.rb
index e8e437e50..1af57b04b 100644
--- a/backend/app/lib/ark/ark_minter.rb
+++ b/backend/app/lib/ark/ark_minter.rb
@@ -59,8 +59,9 @@ class ArkMinter
 
   # Return true if a given ARK string can be assumed to have been generated by the
   # current ARK minter.  Used during import to determine how to handle incoming
-  # ARK strings.
-  def ark_recognized?(ark)
+  # ARK strings. Also passing the object to which this ARK belongs to if additonal
+  # data would be needed (e.g. the repository for shoulder configuration)
+  def ark_recognized?(ark, obj)
     raise NotImplementedError.new
   end
 
diff --git a/backend/app/lib/ark/smithsonian_ark_minter.rb b/backend/app/lib/ark/smithsonian_ark_minter.rb
index 703a22a7b..acad0e15a 100644
--- a/backend/app/lib/ark/smithsonian_ark_minter.rb
+++ b/backend/app/lib/ark/smithsonian_ark_minter.rb
@@ -11,7 +11,7 @@ class SmithsonianArkMinter < ArkMinter
   end
 
   # Looks like an ARK that ends in a UUID.
-  def ark_recognized?(ark)
+  def ark_recognized?(ark, obj)
     ark =~ %r{/ark:/.*\h{8}-\h{4}-\h{4}-\h{4}-\h{12}$}
   end
 
diff --git a/backend/app/model/ark_name.rb b/backend/app/model/ark_name.rb
index 8e0af1291..3cbf7767d 100644
--- a/backend/app/model/ark_name.rb
+++ b/backend/app/model/ark_name.rb
@@ -172,7 +172,7 @@ class ArkName < Sequel::Model(:ark_name)
                                    :retired_at_epoch_ms => 0,
                                    :version_key => EXTERNAL_ARK_VERSION_KEY))
         else
-          if ark_minter.ark_recognized?(ark_name['current'])
+          if ark_minter.ark_recognized?(ark_name['current'], obj)
             ArkName.insert(ark.merge(:ark_value => clean_ark_value(ark_name['current']),
                                      :is_external_url => 0,
                                      :is_current => 1,
@@ -191,7 +191,7 @@ class ArkName < Sequel::Model(:ark_name)
       now_i = (now.to_f * 1000).to_i
 
       ark_name['previous'].each_with_index do |prev, ix|
-        if ark_minter.ark_recognized?(prev)
+        if ark_minter.ark_recognized?(prev, obj)
           ArkName.insert(ark.merge(:ark_value => clean_ark_value(prev),
                                    :is_current => 0,
                                    :is_external_url => 0,
-- 
2.34.1

TODO

The following situation regarding concurrency must be avoided:

read minter state from DB
           |
          mint               read minter state from DB
           |                            |
write minter state to DB               mint
                                        |
                             write minter state to DB

There the second minting process would read a (soon to be) outdated minter state and this would lead to the same ARK being minted when sequential templates are used. I'm not sure if that is possible within the ArchivesSpace architecture but if it is it needs to be solved by some pessimistic database locking or some other sort of FIFO processing.

License

Educational Community License, version 2.0

About

NOIDs for ArchivesSpace


Languages

Language:Ruby 62.0%Language:HTML 38.0%