diff --git a/README.md b/README.md index c0e2212..eae2a31 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # IrusAnalytics -IrusAnalytics is a gem that provides a simple way to send analytics to the IRUS repository aggregation service. +IrusAnalytics is a gem that provides a simple way to send analytics to the IRUS repository aggregation service. -More information about IRUS can be found at [https://irus.jisc.ac.uk/r5/](https://irus.jisc.ac.uk/r5/). In summary the IRUS service is designed to provide item-level usage statistics, both for Investigations (views) and Requests (downloads), for Institutional Repositories. To sign up and use IRUS, please see the above link. +More information about IRUS can be found at [https://irus.jisc.ac.uk/r5/](https://irus.jisc.ac.uk/r5/). In summary the IRUS service is designed to provide item-level usage statistics, both for Investigations (views) and Requests (downloads), for Institutional Repositories. To sign up and use IRUS, please see the above link. -This gem was developed for use with a Hyrax repository [http://samvera.org/](http://samvera.org/), but it can be used with any other web application supporting Ruby gems. +This gem was developed for use with a Hyrax repository [http://samvera.org/](http://samvera.org/), but it can be used with any other web application supporting Ruby gems. More information on COUNTER reports and reporting can be found at [Project COUNTER](https://www.projectcounter.org/) @@ -51,7 +51,7 @@ This uses a similar mechanism to the standard rails database.yml file to allow f is used to define the IRUS server endpoint, this can be configured for the test version of the service. **robots_file**\ -is used to specify the name of the file containing the robot UserAgents as regular expressions. +is used to specify the name of the file containing the robot UserAgents as regular expressions. **Example installed file** @@ -211,8 +211,8 @@ end Therefore in summary... - include IrusAnalytics::Controller::AnalyticsBehaviour - + include IrusAnalytics::Controller::AnalyticsBehaviour + after_filter :send_analytics, only: [:show] def item_identifier_for_irus_analytics @@ -223,19 +223,7 @@ Therefore in summary... NOTE: If you are not using the [Blacklight OAI Provider](https://github.com/projectblacklight/blacklight_oai_provider) gem to create your OAI feed, you'll need to modify the `item_identifier_for_irus_analytics` method to conform with your application's [OAI identifiers](http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm). -To be compliant with the IRUS client requirements/recommendations this Gem makes use of the Resque [https://github.com/resque/resque](https://github.com/resque/resque). Resque provides a simple way to create background jobs within your Ruby application, and is specifically used within this gem to push the analytics posts onto a queue. This means the download functionality within your application is unaffected by the send analytics call, and it provides a means of queuing analytics if the IRUS server is down. - -Note: Resque requires Redis to be installed - -By installing this gem, your application should have access to the Resque rake tasks. These can be seen by running "rake -T", the list should include:- - - rake resque:failures:sort - rake resque:work - rake resque:workers - -To start the resque background job for this gem use - - QUEUE=irus_analytics rake environment resque:work +To be compliant with the IRUS client requirements/recommendations this Gem makes use of the ActiveJob. Any working ActiveJob adapter should work for the processing of the background jobs and is specifically used within this gem to push the analytics posts onto a queue. This means the download functionality within your application is unaffected by the send analytics call, and it provides a means of queuing analytics if the IRUS server is down. ## Additional Notes for Hyrax diff --git a/Rakefile b/Rakefile index 6ed586c..8984f44 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,5 @@ require "bundler/gem_tasks" require "rspec/core/rake_task" -require "resque/tasks" # Default directory to look in is `/specs` # Run with `rake spec` diff --git a/config/locales/irus_analytics.en.yml b/config/locales/irus_analytics.en.yml index 5a47800..6edf39e 100644 --- a/config/locales/irus_analytics.en.yml +++ b/config/locales/irus_analytics.en.yml @@ -5,7 +5,7 @@ en: exited: '%{method} exited' no_server_address: No server address params_extracted: '%{method} parameters extracted' - enquing_error: 'Problem enqueing the analytics with Resque. Error: %{error}' + enquing_error: 'Problem enqueing the analytics job. Error: %{error}' tracker_context: # These transport layer codes don't belong here, see irus_analytics/elements.rb # handles: # see: https://irus.jisc.ac.uk/r5/about/policies/tracker/ diff --git a/irus_analytics.gemspec b/irus_analytics.gemspec index c9f29f4..c2aa075 100644 --- a/irus_analytics.gemspec +++ b/irus_analytics.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_dependency "openurl" # https://github.com/openurl/openurl - spec.add_dependency "resque" + spec.add_dependency "activejob" spec.add_dependency 'config_files' # https://github.com/blackrat/config_files spec.add_dependency 'i18n' diff --git a/lib/generators/irus_analytics/config/templates/irus_analytics.en.yml b/lib/generators/irus_analytics/config/templates/irus_analytics.en.yml index 5a47800..d046348 100644 --- a/lib/generators/irus_analytics/config/templates/irus_analytics.en.yml +++ b/lib/generators/irus_analytics/config/templates/irus_analytics.en.yml @@ -5,7 +5,7 @@ en: exited: '%{method} exited' no_server_address: No server address params_extracted: '%{method} parameters extracted' - enquing_error: 'Problem enqueing the analytics with Resque. Error: %{error}' + enquing_error: 'Problem enqueing the analytics with background job. Error: %{error}' tracker_context: # These transport layer codes don't belong here, see irus_analytics/elements.rb # handles: # see: https://irus.jisc.ac.uk/r5/about/policies/tracker/ diff --git a/lib/irus_analytics.rb b/lib/irus_analytics.rb index 4794fc2..eeaa09c 100644 --- a/lib/irus_analytics.rb +++ b/lib/irus_analytics.rb @@ -1,5 +1,5 @@ -require "resque/server" require 'irus_analytics/elements' +require 'active_job' require 'irus_analytics/irus_analytics_logger' if defined?(Rails) require 'rails/generators' diff --git a/lib/irus_analytics/application_job_fallback.rb b/lib/irus_analytics/application_job_fallback.rb new file mode 100644 index 0000000..c345244 --- /dev/null +++ b/lib/irus_analytics/application_job_fallback.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +unless defined?(ApplicationJob) + class ApplicationJob < ActiveJob::Base + end +end diff --git a/lib/irus_analytics/configuration.rb b/lib/irus_analytics/configuration.rb index 0d99e4d..cea2ffc 100644 --- a/lib/irus_analytics/configuration.rb +++ b/lib/irus_analytics/configuration.rb @@ -32,11 +32,13 @@ class << self define_method name do rv = nil - if defined?( Settings ) && Settings.hostname.present? - if irus_analytics_config[Rails.env][:named_servers].present? - named_server = Settings.hostname - rv = irus_analytics_config[Rails.env][named_server][name.to_s] - end + # Handle multi-tenant hyku _and_ hyrax, both of them using the named_servers section of the config file + if irus_analytics_config[Rails.env]['named_servers'].present? + # hyrax? + named_server = Settings.hostname if defined?( Settings ) && Settings.hostname.present? + # hyku? + named_server = Site.account.cname if defined?( Site ) && Site.account&.cname.present? + rv = irus_analytics_config[Rails.env][named_server][name.to_s] if irus_analytics_config[Rails.env][named_server].present? end rv = irus_analytics_config[Rails.env][name.to_s] if rv.blank? rv diff --git a/lib/irus_analytics/controller/analytics_behaviour.rb b/lib/irus_analytics/controller/analytics_behaviour.rb index 69bf751..e923aa5 100644 --- a/lib/irus_analytics/controller/analytics_behaviour.rb +++ b/lib/irus_analytics/controller/analytics_behaviour.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'logger' -require 'resque' require 'active_support/core_ext/module/delegation' require 'irus_analytics/configuration' require 'irus_analytics/irus_analytics_logger' @@ -123,7 +122,7 @@ def enqueue "@identifier=#{@identifier}", "@usage_event_type=#{@usage_event_type}", "" ] if verbose_debug - Resque.enqueue(IrusClient, server, params, @usage_event_type) + IrusClient.perform_later(server, params, @usage_event_type) rescue Exception => e logger.error(%Q(#{I18n.t('.error', method: debugger_method, scope: i18n_scope)}:#{I18n.t('.enquing_error', error: e, scope: i18n_scope)})) end diff --git a/lib/irus_analytics/irus_client.rb b/lib/irus_analytics/irus_client.rb index fd096bb..a5b4502 100644 --- a/lib/irus_analytics/irus_client.rb +++ b/lib/irus_analytics/irus_client.rb @@ -2,28 +2,28 @@ require 'active_support/core_ext/hash/keys' require_relative './irus_analytics_logger' +require_relative './application_job_fallback' module IrusAnalytics - class IrusClient - @queue = :irus_analytics + class IrusClient < ApplicationJob - class << self - def perform(irus_server_address, analytics_params, usage_event_type) - DebugLogger.bold_debug [ DebugLogger.here, - DebugLogger.called_from, - "irus_server_address=#{irus_server_address}", - "analytics_params=#{analytics_params}", - "usage_event_type=#{usage_event_type}", - "" ] if DebugLogger.verbose_debug - service = IrusAnalytics::IrusAnalyticsService.new(irus_server_address) - case usage_event_type - when REQUEST - service.send_analytics_request(analytics_params.deep_symbolize_keys) - when INVESTIGATION - service.send_analytics_investigation(analytics_params.deep_symbolize_keys) - else - service.send_analytics(analytics_params.deep_symbolize_keys) - end + queue_as :irus_analytics + + def perform(irus_server_address, analytics_params, usage_event_type) + DebugLogger.bold_debug [ DebugLogger.here, + DebugLogger.called_from, + "irus_server_address=#{irus_server_address}", + "analytics_params=#{analytics_params}", + "usage_event_type=#{usage_event_type}", + "" ] if DebugLogger.verbose_debug + service = IrusAnalytics::IrusAnalyticsService.new(irus_server_address) + case usage_event_type + when REQUEST + service.send_analytics_request(analytics_params.deep_symbolize_keys) + when INVESTIGATION + service.send_analytics_investigation(analytics_params.deep_symbolize_keys) + else + service.send_analytics(analytics_params.deep_symbolize_keys) end end end diff --git a/lib/irus_analytics/rail_tie.rb b/lib/irus_analytics/rail_tie.rb index de6d0c9..221bc95 100644 --- a/lib/irus_analytics/rail_tie.rb +++ b/lib/irus_analytics/rail_tie.rb @@ -5,9 +5,5 @@ module IrusAnalytics class Railtie < Rails::Railtie railtie_name :irus_analytics - rake_tasks do - load "tasks/resque.rake" - end - end end diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake deleted file mode 100644 index 7570f85..0000000 --- a/lib/tasks/resque.rake +++ /dev/null @@ -1,3 +0,0 @@ -require 'resque/tasks' - -task 'resque:setup' => :environment diff --git a/spec/lib/irus_analytics/controller/analytics_behaviour_spec.rb b/spec/lib/irus_analytics/controller/analytics_behaviour_spec.rb index b8ece8a..dcfc350 100644 --- a/spec/lib/irus_analytics/controller/analytics_behaviour_spec.rb +++ b/spec/lib/irus_analytics/controller/analytics_behaviour_spec.rb @@ -40,12 +40,13 @@ def skip_send_irus_analytics?(_usage_event_type) http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" } - allow(Resque).to receive(:enqueue) .and_return(nil) # Should NOT filter this request expect(@test_class).to receive(:filter_request?).and_return(false) - expect(Resque).to receive(:enqueue).with(IrusAnalytics::IrusClient, - "irus-server-address.org", - params, IrusAnalytics::REQUEST ) + expect(IrusAnalytics::IrusClient).to receive(:perform_later).with( + "irus-server-address.org", + params, + IrusAnalytics::REQUEST + ).and_return(nil) @test_class.send_irus_analytics end @@ -64,14 +65,13 @@ def skip_send_irus_analytics?(_usage_event_type) http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" } - allow(Resque).to receive(:enqueue).and_return(nil) expect(@test_class).to_not receive(:filter_request?) - expect(Resque).to_not receive(:enqueue) + expect(IrusAnalytics::IrusClient).to_not receive(:perform_later) @test_class.send_irus_analytics end it "will not call the send_irus_analytics method when there is a filter user-agent.." do - # Add a well known robot... + # Add a well known robot... @test_class.request = double("request", :remote_ip => "127.0.0.1", :user_agent => "Microsoft URL Control - 6.00.8862", url: "http://localhost:3000/test", referer: "http://localhost:3000", headers: { "HTTP_RANGE" => nil }) # We set the datetime stamp to ensure sync date_time = "2014-06-09T16:56:48Z" @@ -81,15 +81,18 @@ def skip_send_irus_analytics?(_usage_event_type) params = { date_stamp: date_time, client_ip_address: "127.0.0.1", user_agent: "Microsoft URL Control - 6.00.8862" ,item_oai_identifier: "test:123", file_url: "http://localhost:3000/test", http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" } - allow(Resque).to receive(:enqueue) .and_return(nil) # Should filter this request - expect(Resque).to_not receive(:enqueue).with(IrusAnalytics::IrusClient, "irus-server-address.org", params ) + expect(IrusAnalytics::IrusClient).to_not receive(:perform_later).with( + "irus-server-address.org", + params + ) + @test_class.send_irus_analytics end it "will not call the send_irus_analytics method when the request is expecting a chunk of data (HTTP_RANGE downloading data)." do - # Add a well known robot... + # Add a well known robot... @test_class.request = double("request", :remote_ip => "127.0.0.1", :user_agent =>"Test user agent", url: "http://localhost:3000/test", referer: "http://localhost:3000", headers: { "HTTP_RANGE" => "bytes=0-65535"}) # We set the datetime stamp to ensure sync date_time = "2014-06-09T16:56:48Z" @@ -99,12 +102,15 @@ def skip_send_irus_analytics?(_usage_event_type) params = { date_stamp: date_time, client_ip_address: "127.0.0.1", user_agent: "Microsoft URL Control - 6.00.8862" ,item_oai_identifier: "test:123", file_url: "http://localhost:3000/test", http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" } - allow(Resque).to receive(:enqueue) .and_return(nil) # Should filter this request - expect(Resque).to_not receive(:enqueue).with(IrusAnalytics::IrusClient, "irus-server-address.org", params ) + expect(IrusAnalytics::IrusClient).to_not receive(:perform_later).with( + "irus-server-address.org", + params + ) + @test_class.send_irus_analytics end - end + end end