Skip to content

Commit

Permalink
Update Records from Plum automatically.
Browse files Browse the repository at this point in the history
This subscribes to Plum's RabbitMQ exchange and uses the events there to
keep Pomegranate up to date with Plum.
  • Loading branch information
Trey Terrell committed Feb 23, 2016
1 parent 17fdb2b commit e32a8aa
Show file tree
Hide file tree
Showing 20 changed files with 2,321 additions and 7 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ gem 'social-share-button'
gem 'devise_invitable'
gem 'iiif-presentation'
gem 'omniauth-cas'
gem 'sneakers'
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ GEM
acts-as-taggable-on (3.5.0)
activerecord (>= 3.2, < 5)
addressable (2.4.0)
amq-protocol (2.0.1)
arel (6.0.3)
ast (2.2.0)
astrolabe (1.3.1)
Expand Down Expand Up @@ -113,6 +114,8 @@ GEM
bootstrap_form (2.3.0)
breadcrumbs_on_rails (2.3.1)
builder (3.2.2)
bunny (2.2.2)
amq-protocol (>= 2.0.1)
byebug (8.2.1)
cancancan (1.13.1)
capistrano (3.4.0)
Expand Down Expand Up @@ -410,6 +413,9 @@ GEM
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
serverengine (1.5.11)
sigdump (~> 0.2.2)
sigdump (0.2.3)
signet (0.7.2)
addressable (~> 2.3)
faraday (~> 0.9)
Expand All @@ -427,6 +433,11 @@ GEM
sitemap_generator (5.1.0)
builder
slop (3.6.0)
sneakers (2.3.5)
bunny (~> 2.2.0)
serverengine (~> 1.5.11)
thor
thread (~> 0.1.7)
social-share-button (0.1.10)
coffee-rails
sass-rails
Expand All @@ -448,6 +459,7 @@ GEM
diffy (~> 3.0)
nokogiri (>= 1.3.2)
thor (0.19.1)
thread (0.1.7)
thread_safe (0.3.5)
tilt (2.0.2)
tins (1.6.0)
Expand Down Expand Up @@ -522,6 +534,7 @@ DEPENDENCIES
sdoc (~> 0.4.0)
simplecov (~> 0.9)
sitemap_generator
sneakers
social-share-button
spring
sqlite3
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,14 @@ rake spotlight:exhibit
```

After setup, run Pomegranate locally with `rails s`.

### Auto-update from [Plum](https://github.com/pulibrary/plum)

Plum announces events to a durable RabbitMQ fanout exchange. In order to use them, do the
following:

1. Configure the `events` settings in `config/config.yml`
2. Run `WORKERS=PlumEventHandler rake sneakers:run`

This will subscribe to the plum events and update the pomegranate records when they're
created, updated, or deleted.
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

require File.expand_path('../config/application', __FILE__)
require 'rubocop/rake_task'
require 'sneakers/tasks'

Rails.application.load_tasks

Expand Down
27 changes: 27 additions & 0 deletions app/services/plum_event_processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class PlumEventProcessor
attr_reader :event
def initialize(event)
@event = event
end

delegate :process, to: :processor

private

def event_type
event["event"]
end

def processor
case event_type
when "CREATED"
CreateProcessor.new(event)
when "UPDATED"
UpdateProcessor.new(event)
when "DELETED"
DeleteProcessor.new(event)
else
NullProcessor
end
end
end
10 changes: 10 additions & 0 deletions app/services/plum_event_processor/create_processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class PlumEventProcessor
class CreateProcessor < Processor
def process
exhibits.map do |exhibit|
resource = IIIFResource.new(manifest_url: manifest_url, exhibit: exhibit)
resource.save_and_index
end.all?(&:present?)
end
end
end
12 changes: 12 additions & 0 deletions app/services/plum_event_processor/delete_processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class PlumEventProcessor
class DeleteProcessor < Processor
def process
IIIFResource.where(url: manifest_url).each do |resource|
index.delete_by_id resource.id.to_s
index.commit
resource.destroy
end
true
end
end
end
7 changes: 7 additions & 0 deletions app/services/plum_event_processor/null_processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class PlumEventProcessor
class NullProcessor
def self.process
false
end
end
end
26 changes: 26 additions & 0 deletions app/services/plum_event_processor/processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class PlumEventProcessor
class Processor
attr_reader :event
def initialize(event)
@event = event
end

private

def exhibits
Spotlight::Exhibit.where("slug IN (?)", collection_slugs)
end

def manifest_url
event["manifest_url"]
end

def collection_slugs
event["collection_slugs"]
end

def index
Blacklight.default_index.connection
end
end
end
54 changes: 54 additions & 0 deletions app/services/plum_event_processor/update_processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class PlumEventProcessor
class UpdateProcessor < Processor
def process
delete_old_resources
update_existing_resources
create_new_resources
true
end

def delete_old_resources
delete_resources.each do |resource|
index.delete_by_id resource.id.to_s
index.commit
resource.destroy
end
end

def update_existing_resources
IIIFResource.where(url: manifest_url).each(&:save_and_index)
end

def create_new_resources
new_exhibits.each do |exhibit|
IIIFResource.new(manifest_url: manifest_url, exhibit: exhibit).save_and_index
end
end

private

def new_exhibits
Spotlight::Exhibit.where("slug IN (?)", new_exhibit_slugs)
end

def new_exhibit_slugs
collection_slugs - existing_slugs
end

def delete_resources
IIIFResource.where(url: manifest_url).joins(:exhibit).where('spotlight_exhibits.slug IN (?)', delete_slugs)
end

def delete_slugs
existing_slugs - collection_slugs
end

def existing_slugs
existing_resources.map(&:exhibit).map(&:slug)
end

def existing_resources
IIIFResource.where(url: manifest_url)
end
end
end
14 changes: 14 additions & 0 deletions app/workers/plum_event_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class PlumEventHandler
include Sneakers::Worker
from_queue :pomegranate

def work(msg)
msg = JSON.parse(msg)
result = PlumEventProcessor.new(msg).process
if result
ack!
else
reject!
end
end
end
2 changes: 1 addition & 1 deletion bin/jetty_wait
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env sh

until $(curl --output /dev/null --silent --head --fail http://localhost:8983/solr); do
until $(curl --output /dev/null --silent --head --fail http://localhost:8980/solr); do
printf '.'
sleep 1
done
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
- sudo sh bin/ci_kakadu_install.sh
- RAILS_ENV=development bundle exec rake jetty:unzip
- bundle exec rake jetty:configure_solr
- cd jetty && java -Djetty.port=8983 -Dsolr.solr.home=/home/ubuntu/pomegranate/jetty/solr -XX:MaxPermSize=256m -Xmx512m -jar start.jar:
- cd jetty && java -Djetty.port=8980 -Dsolr.solr.home=/home/ubuntu/pomegranate/jetty/solr -XX:MaxPermSize=256m -Xmx512m -jar start.jar:
background: true
- bin/jetty_wait
test:
Expand Down
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ class Application < Rails::Application

# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
config.autoload_paths += %W(#{Rails.root}/app/workers)
end
end
6 changes: 3 additions & 3 deletions config/blacklight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@

development:
adapter: solr
url: <%= ENV['SOLR_URL'] || "http://127.0.0.1:8983/solr/blacklight-core" %>
url: <%= ENV['SOLR_URL'] || "http://127.0.0.1:8980/solr/blacklight-core" %>
test: &test
adapter: solr
url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/solr/blacklight-test" %>
url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8980}/solr/blacklight-test" %>
production: &production
adapter: solr
url: <%= ENV['POMEGRANATE_SOLR_URL'] || "http://127.0.0.1:8983/solr/blacklight-core" %>
url: <%= ENV['POMEGRANATE_SOLR_URL'] || "http://127.0.0.1:8980/solr/blacklight-core" %>
staging:
<<: *production
4 changes: 4 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
defaults: &defaults
all_collection_manifest_url: "https://hydra-dev.princeton.edu/collections/manifest"
events:
server: 'amqp://localhost:5672'
exchange: 'plum_events'

development:
<<: *defaults
all_collection_manifest_url: "http://localhost:3000/collections/manifest"

test:
<<: *defaults
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/sneakers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'sneakers'
require_relative 'pom_config'
Sneakers.configure(
amqp: Pomegranate.config["events"]["server"],
exchange: Pomegranate.config["events"]["exchange"],
exchange_type: :fanout
)
4 changes: 2 additions & 2 deletions config/jetty.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
development:
startup_wait: 15
jetty_port: 8983
jetty_port: 8980
java_version: ">= 1.7"
test:
startup_wait: 60
jetty_port: <%= ENV['TEST_JETTY_PORT'] || 8888 %>
jetty_port: <%= ENV['TEST_JETTY_PORT'] || 8980 %>
<%= ENV['TEST_JETTY_PATH'] ? "jetty_home: " + ENV['TEST_JETTY_PATH'] : '' %>
java_version: ">= 1.7"
production:
Expand Down
Loading

0 comments on commit e32a8aa

Please sign in to comment.