feat: add Active Storage-backed Valkyrie storage adapter#7550
Closed
orangewolf wants to merge 2 commits into
Closed
feat: add Active Storage-backed Valkyrie storage adapter#7550orangewolf wants to merge 2 commits into
orangewolf wants to merge 2 commits into
Conversation
Adds the canonical Rails create_active_storage_tables migration to the .dassie and .koppie test applications and regenerates their schemas, and teaches the hyrax:models generator to run active_storage:install so host applications get the active_storage_* tables alongside Hyrax's own migrations. Both test apps already ship config/storage.yml and set config.active_storage.service per environment; this fills in the missing database tables so upcoming work can stage uploads and store repository files through Active Storage, where switching local disk vs S3 is a single Rails storage configuration change. No behavior change: nothing in Hyrax attaches or reads Active Storage data yet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hyrax::Storage::ActiveStorage is a Valkyrie StorageAdapter that stores repository files as ActiveStorage::Blob records (no Attachment join rows), so the configured Active Storage service — config/storage.yml and config.active_storage.service, or a service_name: given to the adapter instance — decides where the bytes live. Switching a Valkyrie app's repository files between local disk and S3 becomes a Rails storage configuration change; nothing else in Hyrax needs to know. Versioning mirrors Valkyrie::Storage::VersionedDisk semantics, encoded in blob keys instead of file paths: versions are stored under <key_prefix><resource_id>/v-<timestamp>-<filename> and file identifiers circulate as the stable v-current reference form, so Hyrax::FileMetadata#file_identifier survives new versions and the file set Versions tab works unchanged. find_by returns a StreamFile with a lazy blob IO — nothing downloads until content is read, and #disk_path consumers (characterization, derivatives, downloads, riiif) keep working through local materialization. The adapter is registered in koppie as :active_storage_storage (selectable via VALKYRIE_STORAGE_ADAPTER); the default adapter is unchanged. Documentation covers registration and the S3 switch. ActiveFedora file-set storage is untouched, as throughout this chain. Tests: spec/services/hyrax/storage/active_storage_spec.rb runs valkyrie's full 'a Valkyrie::StorageAdapter' shared compliance examples (including upload_version/find_versions/version deletion semantics) plus adapter-specific coverage: stable current-reference ids, content round-trips, disk_path materialization, lazy lookup (no download on find_by), prefix-scoped handles?, slash-containing filenames (branding-style), per-instance service_name, and an integration example through Hyrax::ValkyrieUpload + Hyrax::VersioningService — 23 examples, 0 failures, 1 documented skip (the shared lsof fd-count example, which is environment-sensitive under the full Hyrax stack; its property is covered by an adapter-specific example). Run locally against the koppie test app. One valkyrie shared example exercises Fedora-style adapters' WebMock toggling and lsof, noted in the spec. Depends on the Active Storage enablement PR for test-app tables. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 17, 2026
Member
Author
|
Superseded by #7556 — same change moved to an in-repo branch (active-storage-for-all/valkyrie-storage-adapter) and retitled. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
Hyrax::Storage::ActiveStorage— a ValkyrieStorageAdapterthat stores repository files (PCDM files belonging to file sets, including versions) asActiveStorage::Blobrecords. Part of the non-AF → Active Storage chain; stacked on #7547 (its commit appears in this diff until it merges). Independent of #7548/#7549 — this adapter serves the repository side, they serve the staging side.With this adapter registered, which backend holds repository file bytes is decided by standard Rails configuration —
config/storage.yml+config.active_storage.service, or a per-instanceservice_name:. Switching a Valkyrie app's repository files from local disk to S3 is that one config change; no bespoke Hyrax S3 configuration.Design:
Valkyrie::Storage::VersionedDiskexactly, encoded in blob keys instead of paths: versions live at<key_prefix><resource_id>/v-<millis>-<filename>, and file identifiers circulate in the stablev-current-reference form —Hyrax::FileMetadata#file_identifierstays stable as versions arrive,Hyrax::VersioningServiceand the file-set Versions tab work unchanged (supports?(:versions)and:version_deletionare true).find_byreturns aStreamFilewhose blob IO downloads nothing until content is actually read;#disk_pathconsumers (FITS characterization, derivatives, downloads, riiif) keep working via local materialization — the same pattern as the Fedora adapter.ActiveStorage::Attachmentrows — these are repository files, not app-level attachments (also avoids analyze jobs).:active_storage_storage, selectable viaVALKYRIE_STORAGE_ADAPTER=active_storage_storage; koppie's default adapter is unchanged (a later PR proposes the flip). ActiveFedora file-set storage is untouched, as throughout this chain.documentation/developing-your-hyrax-based-app.md.Dependencies
Tests
Run locally against the koppie (Valkyrie) test app — dockerized Postgres/Solr/Redis:
spec/services/hyrax/storage/active_storage_spec.rb— valkyrie's full'a Valkyrie::StorageAdapter'shared compliance suite (upload/find_by/delete/checksums plus the completeupload_version/find_versions/ version-deletion semantics), plus adapter-specific examples: stable current-reference ids, byte-identical round-trips,disk_pathmaterialization, no download on lookup, prefix-scopedhandles?, slash-containing filenames (collection-branding style), per-instanceservice_name, and an integration example throughHyrax::ValkyrieUpload+Hyrax::VersioningService(ingest → version on re-upload →find_versions== 2). Result: 23 examples, 0 failures, 1 skip.find_by— is covered by a dedicated example. The skip carries this explanation in the spec.RuboCop clean on new files;
git diff --checkclean.🤖 Generated with Claude Code