Skip to content

Commit

Permalink
Resolves #104 by adding support for RabbitMQ messaging for the creati…
Browse files Browse the repository at this point in the history
…on, updates, and deletion of Figgy resources

Increasing the test coverage for the FileSet Resource and the publishing of messages for deleted FileSets

Restructuring the #parents and #collections methods to be exposed by decorators
  • Loading branch information
jrgriffiniii committed Sep 1, 2017
1 parent 786b0ac commit 1932c63
Show file tree
Hide file tree
Showing 16 changed files with 356 additions and 51 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ source "https://rubygems.org"

gem "autoprefixer-rails"
gem "blacklight"
gem 'bunny'
gem "devise-guests", git: "https://github.com/cbeer/devise-guests.git"
gem "flutie"
gem "honeybadger"
Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ GEM
rails (>= 4.2, < 6)
archive-zip (0.7.0)
io-like (~> 0.3.0)
amq-protocol (2.2.0)
arel (8.0.0)
ast (2.3.0)
autoprefixer-rails (7.1.2.3)
Expand Down Expand Up @@ -204,6 +205,8 @@ GEM
bundler-audit (0.6.0)
bundler (~> 1.2)
thor (~> 0.18)
bunny (2.6.6)
amq-protocol (>= 2.1.0)
byebug (9.0.6)
cancancan (1.17.0)
capistrano (3.7.2)
Expand Down Expand Up @@ -236,6 +239,7 @@ GEM
chromedriver-helper (1.1.0)
archive-zip (~> 0.7.0)
nokogiri (~> 1.6)
cliver (0.3.2)
coderay (1.1.1)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
Expand Down Expand Up @@ -758,6 +762,7 @@ DEPENDENCIES
browse-everything
bullet
bundler-audit (>= 0.5.0)
bunny
capistrano (~> 3.7.1)
capistrano-passenger
capistrano-rails
Expand Down
18 changes: 18 additions & 0 deletions app/change_set_persisters/plum_change_set_persister.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ def save(change_set:)
end

def delete(change_set:)
deleted_resource = change_set.resource
if change_set.resource.is_a?(FileSet)
deleted_resource = change_set.resource.decorate.parents.first unless change_set.resource.decorate.parents.empty?

This comment has been minimized.

Copy link
@escowles

escowles Sep 1, 2017

Member

If we are finding the parent of the FileSet, and then sending the delete event on the parent, wouldn't that send a delete message when you removed a page from a ScannedResource?

end
before_delete(change_set: change_set)
persister.delete(resource: change_set.resource).tap do
after_commit unless transaction?
end
messenger.record_deleted(deleted_resource)
end

def save_all(change_sets:)
Expand Down Expand Up @@ -55,6 +60,13 @@ def with(metadata_adapter:)

private

##
#
# Retrieve the messenger for RabbitMQ
def messenger
@messenger ||= ManifestEventGenerator.new(Figgy.messaging_client)
end

def before_save(change_set:)
apply_remote_metadata(change_set: change_set)
create_files(change_set: change_set)
Expand All @@ -69,6 +81,12 @@ def before_save(change_set:)

def after_save(change_set:, updated_resource:)
append(append_id: change_set.append_id, updated_resource: updated_resource) if change_set.append_id.present?
# Update after having appended a FileSet to a Work, or updated a Work
if updated_resource.is_a? FileSet
messenger.record_updated(updated_resource.decorate.parents.first) unless updated_resource.decorate.parents.empty?
else
messenger.record_updated(updated_resource)
end
end

def before_delete(change_set:)
Expand Down
6 changes: 6 additions & 0 deletions app/decorators/collection_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ def title
def manageable_files?
false
end

# Nested collections are not currently supported
def parents
[]
end
alias collections parents

This comment has been minimized.

Copy link
@escowles

escowles Sep 1, 2017

Member

I'm only seeing FileSet.parents and ScannedResource.collections being called — do we need parents or collections here?

end
8 changes: 8 additions & 0 deletions app/decorators/file_set_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ class FileSetDecorator < Valkyrie::ResourceDecorator
def manageable_files?
false
end

def parents
Valkyrie::MetadataAdapter.find(:indexing_persister).query_service.find_parents(resource: self).to_a
end

def collections

This comment has been minimized.

Copy link
@escowles

escowles Sep 1, 2017

Member

Same as above — I'm not seeing anything that would call this, do we need it?

[]
end
end
5 changes: 5 additions & 0 deletions app/decorators/scanned_resource_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ def iiif_manifest_attributes

current_attributes
end

def parents
Valkyrie::MetadataAdapter.find(:indexing_persister).query_service.find_references_by(resource: self, property: :member_of_collection_ids).to_a

This comment has been minimized.

Copy link
@escowles

escowles Sep 1, 2017

Member

Do we need to handle multi-volume ScannedResources here?

end
alias collections parents

This comment has been minimized.

Copy link
@escowles

escowles Sep 1, 2017

Member

I see code that calls collections, but not parents — do we need both? If we only need collections, then maybe it should handle finding parent ScannedResources and their collections?

end
51 changes: 51 additions & 0 deletions app/services/manifest_event_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true
class ManifestEventGenerator
attr_reader :rabbit_exchange
def initialize(rabbit_exchange)
@rabbit_exchange = rabbit_exchange
end

def record_created(record)
publish_message(
message_with_collections("CREATED", record)
)
end

def record_deleted(record)
publish_message(
message("DELETED", record)
)
end

def record_updated(record)
publish_message(
message_with_collections("UPDATED", record)
)
end

private

def message(type, record)
{
"id" => record ? record.id.to_s : nil,
"event" => type,
"manifest_url" => helper.polymorphic_url([:manifest, record])
}
end

def message_with_collections(type, record)
output = message(type, record)
if record.decorate.respond_to? :collections
output["collection_slugs"] = record.decorate.collections.map { |collection| collection.try(:slug) }.compact
end
output
end

def publish_message(message)
rabbit_exchange.publish(message.to_json)
end

def helper
@helper ||= ManifestBuilder::ManifestHelper.new
end
end
27 changes: 27 additions & 0 deletions app/services/messaging_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true
class MessagingClient
attr_reader :amqp_url
def initialize(amqp_url)
@amqp_url = amqp_url
end

def publish(message)
exchange.publish(message, persistent: true)
rescue
Rails.logger.warn "Unable to publish message to #{amqp_url}"
end

private

def bunny_client
@bunny_client ||= Bunny.new(amqp_url).tap(&:start)
end

def channel
@channel ||= bunny_client.create_channel
end

def exchange
@exchange ||= channel.fanout(Figgy.config['events']['exchange']['plum'], durable: true)
end
end
105 changes: 55 additions & 50 deletions config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,72 @@ defaults: &defaults
plum_derivative_path: "/mnt/libimages1/data/jp2s/plum_prod"
jp2_recipes:
default_color: >
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sRGB
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sRGB
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
Stiles=\{1024,1024\}
default_gray: >
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sLUM
-double_buffering 10
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sLUM
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
Stiles=\{1024,1024\}
geo_color: >
-no_palette
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sRGB
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sRGB
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
Stiles=\{1024,1024\}
geo_gray: >
-no_palette
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sLUM
-double_buffering 10
-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
-jp2_space sLUM
-double_buffering 10
-num_threads 1
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
-no_weights
Clevels=6
Clayers=8
Cblk=\{64,64\}
Cuse_sop=yes
Cuse_eph=yes
Corder=RPCL
ORGgen_plt=yes
ORGtparts=R
Stiles=\{1024,1024\}
events:
server: 'amqp://localhost:5672'
exchange:
plum: "plum_events"
geoblacklight: "gbl_events"

development:
<<: *defaults
Expand Down
11 changes: 10 additions & 1 deletion config/initializers/figgy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ def config
@config ||= config_yaml.with_indifferent_access
end

def messaging_client
@messaging_client ||= MessagingClient.new(Figgy.config['events']['server'])
end

def geoblacklight_messaging_client
@geoblacklight_messaging_client ||= GeoblacklightMessagingClient.new(Figgy.config['events']['server'])
end

def default_url_options
# @default_url_options ||= Rails.application.config.action_mailer.default_url_options
@default_url_options ||= ActionMailer::Base.default_url_options
end

Expand All @@ -14,5 +23,5 @@ def config_yaml
YAML.safe_load(ERB.new(File.read(Rails.root.join("config", "config.yml"))).result, [], [], true)[Rails.env]
end

module_function :config, :config_yaml, :default_url_options
module_function :config, :config_yaml, :messaging_client, :geoblacklight_messaging_client, :default_url_options
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true
Rails.application.routes.draw do
resources :auth_tokens
default_url_options Rails.application.config.action_mailer.default_url_options
concern :exportable, Blacklight::Routes::Exportable.new

resources :solr_documents, only: [:show], path: '/catalog', controller: 'catalog' do
Expand Down
Loading

0 comments on commit 1932c63

Please sign in to comment.