-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DP-827: Adds the watcher CLI command
- Loading branch information
1 parent
8a253c0
commit 6537dcf
Showing
21 changed files
with
305 additions
and
60 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,21 @@ | ||
/log/* | ||
/zold_app/* | ||
/data/* | ||
/tmp/* | ||
/import/* | ||
.irb_history | ||
.bash_history | ||
.bundle/* | ||
./local/* | ||
|
||
/data/* | ||
!/data/gingr | ||
/data/gingr/ready/* | ||
/data/gingr/processed/* | ||
/data/gingr/failed/* | ||
|
||
/solr/geodata-test/data | ||
/solr/geodata-test/data | ||
/solr/geodata/data | ||
/solr/geodata/data | ||
|
||
!**/.keep |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,5 @@ gem 'uri' | |
group :test do | ||
gem 'rspec', '~> 3.12' | ||
end | ||
|
||
gem "listen", "~> 3.8" |
This file contains 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
This file contains 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
Empty file.
Binary file not shown.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
require 'thor' | ||
require_relative 'config' | ||
require_relative 'import_util' | ||
require_relative 'watcher' | ||
|
||
module Gingr | ||
class Cli < Thor | ||
|
@@ -10,6 +11,23 @@ class Cli < Thor | |
|
||
Thor.check_unknown_options! | ||
|
||
desc 'watch', 'Watches a Gingr directory for files ready to be processed' | ||
long_desc <<-TEXT, wrapping: false | ||
EXAMPLES | ||
gingr watch data/gingr --solr-url=https://foo:[email protected]:8983/solr/geodata ... | ||
TEXT | ||
option :solr_url | ||
option :update_reference_field, type: :boolean, default: false | ||
option :spatial_root | ||
option :geoserver_root | ||
option :geoserver_url | ||
option :geoserver_secure_url | ||
def watch(root_dir = nil) | ||
root_dir ||= ENV['GINGR_WATCH_DIRECTORY'] || '/opt/app/data/gingr' | ||
watcher = Gingr::Watcher.new(root_dir, *options) | ||
watcher.start! | ||
end | ||
|
||
desc 'solr', | ||
'Giving a directory path, it will index all json files from the directory/sub-directory to solr' | ||
long_desc <<-TEXT, wrapping: false | ||
|
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# frozen_string_literal: true | ||
require 'listen' | ||
require 'open3' | ||
require_relative 'config' | ||
|
||
module Gingr | ||
class Watcher | ||
include Config | ||
|
||
# Only watch for files in WATCHED_DIRECTORIES[:READY] that match this pattern | ||
WATCH_FILTER = Regexp.compile(/\.zip$/) | ||
|
||
WATCHED_DIRECTORIES = { | ||
# Directory into which new files are dropped when ready for processing. | ||
# .watch! monitors this for new .zip's. | ||
READY: 'ready'.freeze, | ||
# Directory into which successfully processed files are moved post-processing. | ||
PROCESSED: 'processed'.freeze, | ||
# Directory into which failed files are moved post-processing. | ||
FAILED: 'failed'.freeze, | ||
} | ||
|
||
attr_reader :options | ||
attr_reader :root_dir | ||
|
||
def initialize(root_dir, *options) | ||
# This is the Gingr root directory, not the directory to be watched. | ||
# Watcher watches the ./ready directory under this one. | ||
@root_dir = root_dir | ||
|
||
# Options are passed as-is to `gingr all`, so they should match the | ||
# arguments you'd otherwise pass to that command | ||
@options = options | ||
|
||
validate_directories! | ||
end | ||
|
||
def start! | ||
start | ||
sleep | ||
end | ||
|
||
def start | ||
Config.logger.info("Monitoring directory for new zipfiles: #{ready_dir}") | ||
listener.start unless listener.processing? | ||
end | ||
|
||
def listener | ||
@listener ||= begin | ||
Listen.to(ready_dir, only: WATCH_FILTER, force_polling: true) do |_, added, _| | ||
added.each do |zipfile| | ||
Config.logger.info("Processing zipfile: #{zipfile}") | ||
|
||
begin | ||
exec_gingr_all!(zipfile) | ||
rescue => e | ||
Config.logger.error("Error processing #{zipfile}, moving to #{failed_dir}: #{e.inspect}") | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
def exec_gingr_all!(zipfile) | ||
begin | ||
command = ['gingr', 'all', zipfile, *options] | ||
Config.logger.debug("Running command: #{command}") | ||
|
||
stdout, stderr, status = Open3.capture3(*command) | ||
if !status.success? | ||
raise SubprocessError, "Call to `gingr all` failed: #{status}" | ||
end | ||
|
||
Config.logger.debug("Processed #{zipfile}, moving to #{processed_dir}") | ||
FileUtils.mv(zipfile, processed_dir) | ||
rescue => e | ||
FileUtils.mv(zipfile, failed_dir) | ||
File.write(error_log_for(zipfile), collate_logs(stdout, stderr)) | ||
raise | ||
end | ||
end | ||
|
||
def ready_dir | ||
@ready_dir ||= File.join(@root_dir, WATCHED_DIRECTORIES[:READY]) | ||
end | ||
|
||
def processed_dir | ||
@processed_dir ||= File.join(@root_dir, WATCHED_DIRECTORIES[:PROCESSED]) | ||
end | ||
|
||
def failed_dir | ||
@failed_dir ||= File.join(@root_dir, WATCHED_DIRECTORIES[:FAILED]) | ||
end | ||
|
||
private | ||
|
||
def collate_logs(stdout, stderr) | ||
"#{stdout}\n#{stderr}\n" | ||
end | ||
|
||
def error_log_for(zipfile) | ||
File.join(failed_dir, "#{File.basename(zipfile, '.*')}.log") | ||
end | ||
|
||
def validate_directories! | ||
WATCHED_DIRECTORIES.values | ||
.collect { |dirname| public_send("#{dirname}_dir") } | ||
.each &method(:validate_directory!) | ||
end | ||
|
||
def validate_directory!(directory) | ||
if !File.writable?(directory) | ||
raise DirectoryError, "Directory is not writable: #{directory}" | ||
end | ||
end | ||
|
||
# Typed errors to help with tests / figuring out what exactly failed | ||
class WatcherError < StandardError; end | ||
class DirectoryError < WatcherError; end | ||
class SubprocessError < WatcherError; end | ||
end | ||
end |
This file was deleted.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.