From ba9f08076cb6ee3d4746823def90d02fbc339dc3 Mon Sep 17 00:00:00 2001 From: Yetrina Battad Date: Wed, 30 Aug 2023 15:12:38 +1000 Subject: [PATCH] feat: cache eresources config in Redis --- app/models/eresources.rb | 62 +++++++--------------------------- spec/models/eresources_spec.rb | 43 ----------------------- spec/support/webmock.rb | 4 +-- 3 files changed, 14 insertions(+), 95 deletions(-) diff --git a/app/models/eresources.rb b/app/models/eresources.rb index 8b59a431..b0678326 100644 --- a/app/models/eresources.rb +++ b/app/models/eresources.rb @@ -1,18 +1,13 @@ # frozen_string_literal: true -require "json" -require "down" -require "fileutils" -require "caching/eresources_cache" - class Eresources include ActiveModel::Model attr_accessor :entries def initialize - @entries = Caching::EresourcesCache.instance.fetch(["eresources_config"], race_condition_ttl: 10.seconds, expires_in: 4.hours) do - fetch_latest_config + @entries = Rails.cache.fetch("eresources_config", expires_in: 4.hours) do + fetch_config end end @@ -39,51 +34,18 @@ def known_url(url) private - def fetch_latest_config - Rails.logger.info "Fetching latest eResources config" - - config = nil - begin - tempfile = Down.download(ENV["ERESOURCES_CONFIG_URL"], headers: {"User-Agent" => "nla-blacklight/#{Rails.configuration.version}"}) - if tempfile.present? && tempfile.status.include?("200") && valid_json?(tempfile) - same = if File.exist? current_config_path - FileUtils.compare_file(current_config_path, tempfile.path) - else - false - end - - if same - Rails.logger.info "eResources config has not changed. Keeping current config." - elsif File.exist?(current_config_path) && ((File.size(current_config_path) - File.size(tempfile.path)).abs / File.size(current_config_path) > 0.5) - # compare the filesizes - Rails.logger.error "Suspicious difference in file size between latest and current config. Keeping current config." - else - FileUtils.mv(tempfile.path, current_config_path) - Rails.logger.info "eResources config updated" - end - else - Rails.logger.error "Failed to retrieve latest eResources config. Keeping current config." - end - rescue Down::ServerError - Rails.logger.error "Failed to retrieve latest eResources config. Keeping current config." - ensure - if File.exist? current_config_path - config = JSON.parse File.read(current_config_path) + def fetch_config + res = Faraday.get(ENV["ERESOURCES_CONFIG_URL"], nil, {content_type: "application/json", accept: "application/json"}) + if res.status == 200 + if res.body.present? + JSON.parse(res.body) end - end - - config - end - - def valid_json?(tempfile) - !!begin - JSON.parse(File.read(tempfile)) - rescue + else + Rails.logger.error "Failed to retrieve eResources config" nil end - end - - def current_config_path - "#{ENV.fetch("BLACKLIGHT_TMP_PATH", "./tmp")}/cache/eresources.cfg" + rescue => e + Rails.logger.error "Failed to retrieve eResources config: #{e.message}" + nil end end diff --git a/spec/models/eresources_spec.rb b/spec/models/eresources_spec.rb index bd9cea90..dc23ee8c 100644 --- a/spec/models/eresources_spec.rb +++ b/spec/models/eresources_spec.rb @@ -28,35 +28,6 @@ end end - context "when the eResources manager returns a non-200 status" do - let(:current_config) { [{current_config: true}] } - - it "keeps the current config" do - stub_const("ENV", ENV.to_hash.merge("ERESOURCES_CONFIG_URL" => "http://eresource-manager.example.com/service-fail")) - - expect(cache.exist?("eresources_config")).to be(false) - - # setup the current_config - File.write("#{ENV["BLACKLIGHT_TMP_PATH"]}/cache/eresources.cfg", current_config.to_json) - - described_class.new - expect(cache.read("eresources_config")).to eq JSON.parse current_config.to_json - end - - # rubocop:disable RSpec/NestedGroups - context "when there is no previous config" do - it "returns an empty array" do - stub_const("ENV", ENV.to_hash.merge("ERESOURCES_CONFIG_URL" => "http://eresource-manager.example.com/service-fail")) - - expect(cache.exist?("eresources_config")).to be(false) - - described_class.new - expect(cache.read("eresources_config")).to be_nil - end - end - # rubocop:enable RSpec/NestedGroups - end - context "when the latest config is the same as the current config" do # setup the current_config let(:current_config) { File.read("spec/files/eresources/config.txt") } @@ -71,20 +42,6 @@ expect(cache.read("eresources_config")).to eq JSON.parse current_config end end - - context "when file size difference is too great" do - let(:current_config) { [{current_config: true}] } - - it "keeps the current config" do - expect(cache.exist?("eresources_config")).to be(false) - - # setup the current_config - File.write("#{ENV["BLACKLIGHT_TMP_PATH"]}/cache/eresources.cfg", current_config.to_json) - - described_class.new - expect(cache.read("eresources_config")).to eq JSON.parse current_config.to_json - end - end end describe "#url_append" do diff --git a/spec/support/webmock.rb b/spec/support/webmock.rb index 8c21059a..a4d5bdbe 100644 --- a/spec/support/webmock.rb +++ b/spec/support/webmock.rb @@ -12,7 +12,7 @@ WebMock.stub_request(:get, "http://eresource-manager.example.com/") .with( headers: { - "Accept" => "*/*", + "Accept" => "application/json", "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" } ) @@ -21,7 +21,7 @@ WebMock.stub_request(:get, "http://eresource-manager.example.com/service-fail") .with( headers: { - "Accept" => "*/*", + "Accept" => "application/json", "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" } )