diff --git a/app/models/admin_set.rb b/app/models/admin_set.rb index cc98bd4bab..4bdca5dd72 100644 --- a/app/models/admin_set.rb +++ b/app/models/admin_set.rb @@ -16,18 +16,18 @@ # @see Hyrax::DefaultAdminSetActor # @see Hyrax::ApplyPermissionTemplateActor class AdminSet < Valkyrie::Resource - #include Hydra::AccessControls::WithAccessRight + # include Hydra::AccessControls::WithAccessRight include Hyrax::Noid include Hyrax::HumanReadableType - #include Hyrax::HasRepresentative + # include Hyrax::HasRepresentative DEFAULT_ID = 'admin_set/default'.freeze DEFAULT_TITLE = ['Default Admin Set'].freeze DEFAULT_WORKFLOW_NAME = Hyrax.config.default_active_workflow_name - #validates_with Hyrax::HasOneTitleValidator + # validates_with Hyrax::HasOneTitleValidator class_attribute :human_readable_short_description - #self.indexer = Hyrax::AdminSetIndexer + # self.indexer = Hyrax::AdminSetIndexer attribute :id, Valkyrie::Types::ID.optional attribute :title, Valkyrie::Types::Set attribute :description, Valkyrie::Types::Set @@ -48,8 +48,8 @@ class AdminSet < Valkyrie::Resource # predicate: Hyrax.config.admin_set_predicate, # class_name: 'ActiveFedora::Base' - #before_destroy :check_if_not_default_set, :check_if_empty - #after_destroy :destroy_permission_template + # before_destroy :check_if_not_default_set, :check_if_empty + # after_destroy :destroy_permission_template def self.default_set?(id) id == DEFAULT_ID @@ -102,15 +102,15 @@ def destroy_permission_template true end - # def check_if_empty - # return true if members.empty? - # errors[:base] << I18n.t('hyrax.admin.admin_sets.delete.error_not_empty') - # throw :abort - # end - # - # def check_if_not_default_set - # return true unless default_set? - # errors[:base] << I18n.t('hyrax.admin.admin_sets.delete.error_default_set') - # throw :abort - # end + # def check_if_empty + # return true if members.empty? + # errors[:base] << I18n.t('hyrax.admin.admin_sets.delete.error_not_empty') + # throw :abort + # end + # + # def check_if_not_default_set + # return true unless default_set? + # errors[:base] << I18n.t('hyrax.admin.admin_sets.delete.error_default_set') + # throw :abort + # end end diff --git a/app/models/batch_upload_item.rb b/app/models/batch_upload_item.rb index 6aca6bda98..3c97b914a7 100644 --- a/app/models/batch_upload_item.rb +++ b/app/models/batch_upload_item.rb @@ -2,7 +2,7 @@ # It should never actually be persisted in the repository. # The properties on this form should be copied to a real work type. class BatchUploadItem < Valkyrie::Resource - #include Hyrax::WorkBehavior + # include Hyrax::WorkBehavior # This must come after the WorkBehavior because it finalizes the metadata # schema (by adding accepts_nested_attributes) include ::Hyrax::BasicMetadata diff --git a/app/models/concerns/hyrax/basic_metadata.rb b/app/models/concerns/hyrax/basic_metadata.rb index 6725ce5f21..0367af76a1 100644 --- a/app/models/concerns/hyrax/basic_metadata.rb +++ b/app/models/concerns/hyrax/basic_metadata.rb @@ -6,7 +6,6 @@ module BasicMetadata extend ActiveSupport::Concern included do - attribute :label, Valkyrie::Types::SingleValuedString # property :label, predicate: ActiveFedora::RDF::Fcrepo::Model.downloadFilename, multiple: false diff --git a/app/models/concerns/hyrax/collection_behavior.rb b/app/models/concerns/hyrax/collection_behavior.rb index b31a60a770..0f9a39186f 100644 --- a/app/models/concerns/hyrax/collection_behavior.rb +++ b/app/models/concerns/hyrax/collection_behavior.rb @@ -9,11 +9,11 @@ module CollectionBehavior include Hyrax::Noid include Hyrax::HumanReadableType # include Hyrax::HasRepresentative - # include Hyrax::Permissions + include Hyrax::Permissions included do - # validates_with HasOneTitleValidator - # self.indexer = Hyrax::CollectionIndexer + # validates_with HasOneTitleValidator + # self.indexer = Hyrax::CollectionIndexer end # Add members using the members association. diff --git a/app/models/concerns/hyrax/in_admin_set.rb b/app/models/concerns/hyrax/in_admin_set.rb index 9d63d18eb1..4d7ab112ad 100644 --- a/app/models/concerns/hyrax/in_admin_set.rb +++ b/app/models/concerns/hyrax/in_admin_set.rb @@ -4,7 +4,7 @@ module InAdminSet included do attribute :admin_set_id, Valkyrie::Types::Set - #belongs_to :admin_set, predicate: Hyrax.config.admin_set_predicate + # belongs_to :admin_set, predicate: Hyrax.config.admin_set_predicate end def active_workflow diff --git a/app/models/concerns/hyrax/works/metadata.rb b/app/models/concerns/hyrax/works/metadata.rb index d6ac5a5c4d..a7131499a0 100644 --- a/app/models/concerns/hyrax/works/metadata.rb +++ b/app/models/concerns/hyrax/works/metadata.rb @@ -4,7 +4,7 @@ module Metadata included do attribute :arkivo_checksum, Valkyrie::Types::String - #property :arkivo_checksum, predicate: ::RDF::URI.new('http://scholarsphere.psu.edu/ns#arkivoChecksum'), multiple: false + # property :arkivo_checksum, predicate: ::RDF::URI.new('http://scholarsphere.psu.edu/ns#arkivoChecksum'), multiple: false end end end diff --git a/app/models/hyrax/file_node.rb b/app/models/hyrax/file_node.rb new file mode 100644 index 0000000000..d52576601a --- /dev/null +++ b/app/models/hyrax/file_node.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Hyrax + class FileNode < Valkyrie::Resource + include Valkyrie::Resource::AccessControls + attribute :id, Valkyrie::Types::ID.optional + attribute :label, Valkyrie::Types::Set + attribute :mime_type, Valkyrie::Types::Set + attribute :height, Valkyrie::Types::Set + attribute :width, Valkyrie::Types::Set + attribute :checksum, Valkyrie::Types::Set + attribute :size, Valkyrie::Types::Set + attribute :original_filename, Valkyrie::Types::Set + attribute :file_identifiers, Valkyrie::Types::Set + attribute :use, Valkyrie::Types::Set + + def self.for(file:) + new(label: file.original_filename, original_filename: file.original_filename, mime_type: file.content_type, use: file.try(:use) || [Valkyrie::Vocab::PCDMUse.OriginalFile]) + end + + def title + label + end + + def download_id + id + end + + def valid? + file = Valkyrie::StorageAdapter.find_by(id: file_identifiers.first) + file.valid?(size: size.first, digests: { sha256: checksum.first }) + end + end +end diff --git a/app/persisters/hyrax/indexing_adapter.rb b/app/persisters/hyrax/indexing_adapter.rb index 0047e25f1b..632210d79f 100644 --- a/app/persisters/hyrax/indexing_adapter.rb +++ b/app/persisters/hyrax/indexing_adapter.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # This was copied out of the Valkyrie app and I don't know why it isn't part of # the valkyrie gem. -- Justin ## @@ -61,9 +62,7 @@ def delete(resource:) composite_persister.delete(resource: resource) end - def wipe! - composite_persister.wipe! - end + delegate :wipe!, to: :composite_persister # Yields the primary persister. At the end of the block, this will use changes tracked # by an in-memory persister to replicate new and deleted objects into the diff --git a/app/persisters/hyrax/persister.rb b/app/persisters/hyrax/persister.rb deleted file mode 100644 index 1897898f86..0000000000 --- a/app/persisters/hyrax/persister.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -module Hyrax - # This was copied directly from the Valkyrie app. I don't understand why it - # isn't part of the Valkyrie gem. - class Persister - class_attribute :adapter - self.adapter = Valkyrie.config.metadata_adapter - class << self - delegate :save, :delete, :persister, to: :default_adapter - - def default_adapter - new(adapter: adapter) - end - end - - delegate :save, :delete, :persister, to: :adapted_persister - def initialize(adapter:) - @adapter = adapter - end - - def adapted_persister - adapter.persister - end - end -end diff --git a/app/services/hyrax/file_appender.rb b/app/services/hyrax/file_appender.rb new file mode 100644 index 0000000000..280b7f92d9 --- /dev/null +++ b/app/services/hyrax/file_appender.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Hyrax + class FileAppender + attr_reader :storage_adapter, :persister, :files + def initialize(storage_adapter:, persister:, files:) + @storage_adapter = storage_adapter + @persister = persister + @files = files + end + + def append_to(resource) + return resource if files.blank? + file_sets = build_file_sets || file_nodes + resource.member_ids = resource.member_ids + file_sets.map(&:id) + resource + end + + def build_file_sets + return if processing_derivatives? + file_nodes.map do |node| + file_set = create_file_set(node) + Valkyrie::DerivativeService.for(FileSetChangeSet.new(file_set)).create_derivatives if node.use.include?(Valkyrie::Vocab::PCDMUse.OriginalFile) + file_set + end + end + + def processing_derivatives? + !file_nodes.first.use.include?(Valkyrie::Vocab::PCDMUse.OriginalFile) + end + + def file_nodes + @file_nodes ||= + begin + files.map do |file| + create_node(file) + end + end + end + + def create_node(file) + node = persister.save(resource: FileNode.for(file: file)) + stored_file = storage_adapter.upload(file: file, resource: node) + node.file_identifiers = node.file_identifiers + [stored_file.id] + node = Valkyrie::FileCharacterizationService.for(file_node: node, persister: persister).characterize(save: false) + persister.save(resource: node) + end + + def create_file_set(file_node) + persister.save(resource: ::FileSet.new(title: file_node.original_filename, member_ids: file_node.id)) + end + end +end diff --git a/app/services/hyrax/queries.rb b/app/services/hyrax/queries.rb new file mode 100644 index 0000000000..e1e8f18c53 --- /dev/null +++ b/app/services/hyrax/queries.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Hyrax + class Queries + class_attribute :metadata_adapter + self.metadata_adapter = Valkyrie.config.metadata_adapter + class << self + delegate :find_all, :find_by, :find_members, :find_inverse_references_by, to: :default_adapter + + def default_adapter + new(metadata_adapter: metadata_adapter) + end + end + + attr_reader :metadata_adapter + delegate :find_all, :find_by, :find_members, :find_inverse_references_by, to: :metadata_adapter_query_service + def initialize(metadata_adapter:) + @metadata_adapter = metadata_adapter + end + + delegate :query_service, to: :metadata_adapter, prefix: true + end +end diff --git a/config/initializers/valkyrie.rb b/config/initializers/valkyrie.rb index 2bda20c5c1..68adfd59fd 100644 --- a/config/initializers/valkyrie.rb +++ b/config/initializers/valkyrie.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true + require 'valkyrie' -# TODO move to the host app? +# TODO: move to the host app? +# rubocop:disable Metrics/BlockLength Rails.application.config.to_prepare do Valkyrie::MetadataAdapter.register( Valkyrie::Persistence::Postgres::MetadataAdapter.new, @@ -59,3 +61,4 @@ # Valkyrie::FileCharacterizationService.services << TikaFileCharacterizationService end +# rubocop:enable Metrics/BlockLength diff --git a/spec/factories/collections_factory.rb b/spec/factories/collections_factory.rb index bde6b32ca5..ee16fa39ba 100644 --- a/spec/factories/collections_factory.rb +++ b/spec/factories/collections_factory.rb @@ -9,6 +9,10 @@ work.apply_depositor_metadata(evaluator.user.user_key) end + to_create do |instance| + Valkyrie.config.metadata_adapter.persister.save(resource: instance) + end + factory :public_collection, traits: [:public] trait :public do diff --git a/spec/factories/file_sets.rb b/spec/factories/file_sets.rb index 7cde25c6b5..348b76736b 100644 --- a/spec/factories/file_sets.rb +++ b/spec/factories/file_sets.rb @@ -14,6 +14,10 @@ end end + to_create do |instance| + Valkyrie.config.metadata_adapter.persister.save(resource: instance) + end + trait :public do read_groups ["public"] end diff --git a/spec/models/checksum_audit_log_spec.rb b/spec/models/checksum_audit_log_spec.rb index 8817daed04..1c40c602d3 100644 --- a/spec/models/checksum_audit_log_spec.rb +++ b/spec/models/checksum_audit_log_spec.rb @@ -1,12 +1,17 @@ +include ActionDispatch::TestProcess + RSpec.describe ChecksumAuditLog do + let(:files) { [fixture_file_upload('world.png', 'image/png')] } + let(:persister) { Valkyrie.config.metadata_adapter.persister } + let(:storage_adapter) { Valkyrie.config.storage_adapter } + + let(:file_node) {} let(:f) do - file = FileSet.new do |gf| - gf.apply_depositor_metadata('mjg36') + file = FileSet.new do |fs| + fs.apply_depositor_metadata('mjg36') + fs.member_ids = [file_node.id] end - Hyrax::Persister.save(resource: file) - # TODO: Mock addition of file to fileset to avoid calls to .save. - # This will speed up tests and avoid uneccesary integration testing for fedora funcationality. - Hydra::Works::AddFileToFileSet.call(file, File.open(fixture_path + '/world.png'), :original_file) + persister.save(resource: file) file end diff --git a/spec/models/collection_spec.rb b/spec/models/collection_spec.rb index 2f93f5b6f3..22061acf93 100644 --- a/spec/models/collection_spec.rb +++ b/spec/models/collection_spec.rb @@ -1,5 +1,6 @@ RSpec.describe Collection do let(:collection) { build(:public_collection) } + let(:persister) { Valkyrie.config.metadata_adapter.persister } it "has open visibility" do expect(collection.read_groups).to eq ['public'] @@ -75,11 +76,11 @@ describe "Collection by another name" do before do - class OtherCollection < ActiveFedora::Base + class OtherCollection < Valkyrie::Resource include Hyrax::CollectionBehavior end - class Member < ActiveFedora::Base + class Member < Valkyrie::Resource include Hydra::Works::WorkBehavior end collection.add_member_objects member.id diff --git a/spec/models/file_set_spec.rb b/spec/models/file_set_spec.rb index 5812870ba2..945b230ecd 100644 --- a/spec/models/file_set_spec.rb +++ b/spec/models/file_set_spec.rb @@ -5,12 +5,14 @@ include Hyrax::FactoryHelpers let(:user) { create(:user) } + let(:persister) { Valkyrie.config.metadata_adapter.persister } - describe 'rdf type' do - subject { described_class.new.type } - - it { is_expected.to include(Hydra::PCDM::Vocab::PCDMTerms.Object, Hydra::Works::Vocab::WorksTerms.FileSet) } - end + # TODO: Move to a PCDM persister test + # describe 'rdf type' do + # subject { described_class.new.type } + # + # it { is_expected.to include(Hydra::PCDM::Vocab::PCDMTerms.Object, Hydra::Works::Vocab::WorksTerms.FileSet) } + # end it 'is a Hydra::Works::FileSet' do expect(subject).to be_file_set @@ -121,8 +123,8 @@ subject.related_url = ['http://example.org/'] subject.creator = ['John Doe'] subject.title = ['New work'] - subject.save - f = subject.reload + saved = persister.save(resource: subject) + f = Hyrax::Queries.find_by(id: saved.id) expect(f.related_url).to eq ['http://example.org/'] expect(f.creator).to eq ['John Doe'] expect(f.title).to eq ['New work'] @@ -131,14 +133,14 @@ it 'is able to be added to w/o unexpected graph behavior' do subject.creator = ['John Doe'] subject.title = ['New work'] - subject.save! - f = subject.reload + saved = persister.save(resource: subject) + f = Hyrax::Queries.find_by(id: saved.id) expect(f.creator).to eq ['John Doe'] expect(f.title).to eq ['New work'] f.creator = ['Jane Doe'] f.title += ['Newer work'] - f.save - f = subject.reload + saved = persister.save(resource: f) + f = Hyrax::Queries.find_by(id: saved.id) expect(f.creator).to eq ['Jane Doe'] # TODO: Is order important? expect(f.title).to include('New work') @@ -246,14 +248,14 @@ class AltFile < ActiveFedora::Base end context "after saving" do - before { subject.save! } + let(:saved) { persister.save(resource: subject) } it 'returns the expected identifier' do - expect(subject.id).to eq noid + expect(saved.id).to eq noid end it "has a treeified URL" do - expect(subject.uri.to_s).to end_with '/wd/37/63/09/wd3763094' + expect(saved.uri.to_s).to end_with '/wd/37/63/09/wd3763094' end end @@ -479,23 +481,22 @@ def paranoid_edit_permissions end describe 'to_solr record' do - subject do - described_class.new.tap do |f| - f.apply_depositor_metadata(depositor) - f.save - end + subject(:file_set) do + file_set = described_class.new + file_set.apply_depositor_metadata(depositor) + persister.save(resource: file_set) end let(:depositor) { 'jcoyne' } let(:depositor_key) { Solrizer.solr_name('depositor') } let(:title_key) { Solrizer.solr_name('title', :stored_searchable, type: :string) } let(:title) { ['abc123'] } - let(:no_terms) { described_class.find(subject.id).to_solr } + let(:no_terms) { Hyrax::Queries.find_by(id: file_set.id).to_solr } let(:terms) do - file = described_class.find(subject.id) - file.title = title - file.save - file.to_solr + file_set_anew = Hyrax::Queries.find_by(id: file_set.id) + file_set_anew.title = title + persister.save(resource: file_set_anew) + file_set_anew.to_solr end context 'without terms' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 993f37fb54..5b67d991b5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -153,9 +153,8 @@ def main_app ensure_deposit_available_for(user) if example.metadata[:workflow] if example.metadata[:clean_repo] $stderr.puts "Repository cleaning was requested but is disable presently" - #ActiveFedora::Cleaner.clean! + # ActiveFedora::Cleaner.clean! end - end config.include(ControllerLevelHelpers, type: :view)