qa 5.2.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69b198054c52dafc00d9cf83f2f61b5fdc3e55cb
4
- data.tar.gz: 00aa3d111681efe0a1c068846190e41531155e21
3
+ metadata.gz: a0d1a1143d74f69697643e818b748496f81e96cd
4
+ data.tar.gz: e1145e427c1f343a44b4d144181697efb89a70e4
5
5
  SHA512:
6
- metadata.gz: c75338fdecba820602eb3c669065679a87387e80bf65e350fdc42d6224dc5eb152439198257b6da3eb38812a9e44e6764472fa3a8fff3f554e782b13da0e4c38
7
- data.tar.gz: bcf795d36f8fc600dbc672d9884b4b37efd084ad9e12a7e53583b491cf122b1247f8335fdcfe216cfda6b2c3c326628ac27f2b6a375aa44feb783daf8ce0f2b5
6
+ metadata.gz: 8abeeb72e16fca93102783671e7b8da5362461422e9b3d6d53ed35a0ee7dc7e169980b5ea1eeb53bf1a00edf7fd4d85f41f6336af0b61acc50b56bf7161d5978
7
+ data.tar.gz: ab5983ff28640f912a06ac673b376d1542d4cdd0a182b1cfedf72ea6b186c4ada32ad17c4d9c7190e7e30c18bb81e8377e0603ff984b268ffa9168c59d10aead
@@ -91,6 +91,7 @@ module Qa
91
91
  end
92
92
 
93
93
  def process_error(e, url)
94
+ Rails.logger.warn("******** RDF::Graph#load failure: exception=#{e.inspect}, url=#{url}")
94
95
  uri = URI(url)
95
96
  raise RDF::FormatError, "Unknown RDF format of results returned by #{uri}. (RDF::FormatError) You may need to include gem 'linkeddata'." if e.is_a? RDF::FormatError
96
97
  response_code = ioerror_code(e)
@@ -1,8 +1,9 @@
1
1
  # Service to construct a request header that includes optional attributes for search and fetch requests.
2
+ require 'geocoder'
2
3
  module Qa
3
4
  module LinkedData
4
5
  class RequestHeaderService
5
- attr_reader :request, :params
6
+ attr_reader :request, :params, :request_id
6
7
 
7
8
  # @param request [HttpRequest] request from controller
8
9
  # @param params [Hash] attribute-value pairs holding the request parameters
@@ -16,6 +17,8 @@ module Qa
16
17
  def initialize(request:, params:)
17
18
  @request = request
18
19
  @params = params
20
+ @request_id = request.request_id
21
+ log_request
19
22
  end
20
23
 
21
24
  # Construct request parameters to pass to search_query (linked data module).
@@ -23,6 +26,8 @@ module Qa
23
26
  # @see Qa::Authorities::LinkedData::SearchQuery
24
27
  def search_header
25
28
  header = {}
29
+ header[:request] = request
30
+ header[:request_id] = request_id
26
31
  header[:subauthority] = params.fetch(:subauthority, nil)
27
32
  header[:user_language] = user_language
28
33
  header[:performance_data] = performance_data?
@@ -37,6 +42,8 @@ module Qa
37
42
  # @see Qa::Authorities::LinkedData::FindTerm
38
43
  def fetch_header
39
44
  header = {}
45
+ header[:request] = request
46
+ header[:request_id] = request_id
40
47
  header[:subauthority] = params.fetch(:subauthority, nil)
41
48
  header[:user_language] = user_language
42
49
  header[:performance_data] = performance_data?
@@ -62,6 +69,13 @@ module Qa
62
69
 
63
70
  private
64
71
 
72
+ def log_request
73
+ gc = request.location
74
+ msg = "******** #{request.path_parameters[:action].upcase}"
75
+ msg += " from IP #{request.ip} in {city: #{gc.city}, state: #{gc.state}, country: #{gc.country}}" unless Qa.config.suppress_ip_data_from_log
76
+ Rails.logger.info(msg)
77
+ end
78
+
65
79
  # filter literals in results to this language
66
80
  def user_language
67
81
  request_language = request.env['HTTP_ACCEPT_LANGUAGE']
@@ -23,4 +23,9 @@ Qa.config do |config|
23
23
  # When false, properties that do not override default optional behavior will be shown whether or not the property has a value in the graph.
24
24
  # When true, properties that do not override default optional behavior will not be shown whn the property does not have a value in the graph.
25
25
  # config.property_map_default_for_optional = false
26
+
27
+ # IP data including IP address, city, state, and country will be logged with each request.
28
+ # When false, IP data is logged
29
+ # When true, IP data will not be logged (default for backward compatibility)
30
+ # config.suppress_ip_data_from_log = true
26
31
  end
@@ -15,8 +15,8 @@ module Qa::Authorities
15
15
  @term_config = term_config
16
16
  end
17
17
 
18
- attr_reader :term_config, :full_graph, :filtered_graph, :language, :id, :uri, :access_time_s, :normalize_time_s, :subauthority, :request_header
19
- private :full_graph, :filtered_graph, :language, :id, :uri, :access_time_s, :normalize_time_s, :subauthority, :request_header
18
+ attr_reader :term_config, :full_graph, :filtered_graph, :language, :id, :uri, :access_time_s, :normalize_time_s, :subauthority, :request_header, :request_id, :request
19
+ private :full_graph, :filtered_graph, :language, :id, :uri, :access_time_s, :normalize_time_s, :subauthority, :request_header, :request_id, :request
20
20
 
21
21
  delegate :term_subauthority?, :prefixes, :authority_name, to: :term_config
22
22
 
@@ -92,6 +92,8 @@ module Qa::Authorities
92
92
 
93
93
  def unpack_request_header(request_header)
94
94
  @request_header = request_header
95
+ @request = request_header.fetch(:request, nil)
96
+ @request_id = request_header.fetch(:request_id, 'UNASSIGNED')
95
97
  @subauthority = request_header.fetch(:subauthority, nil)
96
98
  @format = request_header.fetch(:format, 'json')
97
99
  @performance_data = request_header.fetch(:performance_data, false)
@@ -15,8 +15,8 @@ module Qa::Authorities
15
15
  @search_config = search_config
16
16
  end
17
17
 
18
- attr_reader :search_config, :full_graph, :filtered_graph, :language, :access_time_s, :normalize_time_s, :subauthority, :request_header
19
- private :full_graph, :filtered_graph, :language, :access_time_s, :normalize_time_s, :subauthority, :request_header
18
+ attr_reader :search_config, :full_graph, :filtered_graph, :language, :access_time_s, :normalize_time_s, :subauthority, :request_header, :request_id, :request
19
+ private :full_graph, :filtered_graph, :language, :access_time_s, :normalize_time_s, :subauthority, :request_header, :request_id, :request
20
20
 
21
21
  delegate :subauthority?, :supports_sort?, :prefixes, :authority_name, to: :search_config
22
22
 
@@ -91,6 +91,8 @@ module Qa::Authorities
91
91
 
92
92
  def unpack_request_header(request_header)
93
93
  @request_header = request_header
94
+ @request = request_header.fetch(:request, nil)
95
+ @request_id = request_header.fetch(:request_id, 'UNASSIGNED')
94
96
  @subauthority = request_header.fetch(:subauthority, nil)
95
97
  @context = request_header.fetch(:context, false)
96
98
  @performance_data = request_header.fetch(:performance_data, false)
@@ -54,5 +54,14 @@ module Qa
54
54
  @property_map_default_for_optional = false if @property_map_default_for_optional.nil?
55
55
  @property_map_default_for_optional
56
56
  end
57
+
58
+ # IP data including IP address, city, state, and country will be logged with each request.
59
+ # When false, IP data is logged
60
+ # When true, IP data will not be logged (default for backward compatibility)
61
+ attr_writer :suppress_ip_data_from_log
62
+ def suppress_ip_data_from_log
63
+ @suppress_ip_data_from_log = true if @suppress_ip_data_from_log.nil?
64
+ @suppress_ip_data_from_log
65
+ end
57
66
  end
58
67
  end
@@ -1,3 +1,3 @@
1
1
  module Qa
2
- VERSION = "5.2.0".freeze
2
+ VERSION = "5.3.0".freeze
3
3
  end
@@ -2,6 +2,7 @@ require 'spec_helper'
2
2
  require 'json'
3
3
 
4
4
  describe Qa::LinkedDataTermsController, type: :controller do
5
+ let(:graph_load_failure) { /^\*\*\*\*\*\*\*\* RDF\:\:Graph\#load failure/ }
5
6
  before do
6
7
  @routes = Qa::Engine.routes
7
8
  end
@@ -140,6 +141,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
140
141
  .to_return(status: 500)
141
142
  end
142
143
  it 'returns 500' do
144
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
143
145
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Search query my_query unsuccessful for authority OCLC_FAST")
144
146
  get :search, params: { q: 'my_query', vocab: 'OCLC_FAST', maximumRecords: '3' }
145
147
  expect(response.code).to eq('500')
@@ -154,6 +156,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
154
156
  end
155
157
  it 'returns 500' do
156
158
  msg = "RDF Format Error - Results from search query my_query for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem."
159
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
157
160
  expect(Rails.logger).to receive(:warn).with(msg)
158
161
  get :search, params: { q: 'my_query', vocab: 'OCLC_FAST', maximumRecords: '3' }
159
162
  expect(response.code).to eq('500')
@@ -166,6 +169,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
166
169
  .to_return(status: 501)
167
170
  end
168
171
  it 'returns 500' do
172
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
169
173
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Search query my_query unsuccessful for authority OCLC_FAST")
170
174
  get :search, params: { q: 'my_query', vocab: 'OCLC_FAST', maximumRecords: '3' }
171
175
  expect(response.code).to eq('500')
@@ -179,6 +183,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
179
183
  .to_return(status: 503)
180
184
  end
181
185
  it 'returns 503' do
186
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
182
187
  expect(Rails.logger).to receive(:warn).with("Service Unavailable - Search query my_query unsuccessful for authority OCLC_FAST")
183
188
  get :search, params: { q: 'my_query', vocab: 'OCLC_FAST', maximumRecords: '3' }
184
189
  expect(response.code).to eq('503')
@@ -355,6 +360,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
355
360
  stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 500)
356
361
  end
357
362
  it 'returns 500' do
363
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
358
364
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term 530369 unsuccessful for authority OCLC_FAST")
359
365
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
360
366
  expect(response.code).to eq('500')
@@ -380,6 +386,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
380
386
  end
381
387
  it 'returns 500' do
382
388
  msg = "RDF Format Error - Results from fetch term 530369 for authority OCLC_FAST was not identified as a valid RDF format. You may need to include the linkeddata gem."
389
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
383
390
  expect(Rails.logger).to receive(:warn).with(msg)
384
391
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
385
392
  expect(response.code).to eq('500')
@@ -391,6 +398,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
391
398
  stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 501)
392
399
  end
393
400
  it 'returns 500' do
401
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
394
402
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term 530369 unsuccessful for authority OCLC_FAST")
395
403
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
396
404
  expect(response.code).to eq('500')
@@ -403,6 +411,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
403
411
  stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 503)
404
412
  end
405
413
  it 'returns 503' do
414
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
406
415
  expect(Rails.logger).to receive(:warn).with("Service Unavailable - Fetch term 530369 unsuccessful for authority OCLC_FAST")
407
416
  get :show, params: { id: '530369', vocab: 'OCLC_FAST' }
408
417
  expect(response.code).to eq('503')
@@ -414,6 +423,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
414
423
  stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID').to_return(status: 404, body: '', headers: {})
415
424
  end
416
425
  it 'returns 404' do
426
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
417
427
  expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term FAKE_ID unsuccessful for authority OCLC_FAST')
418
428
  get :show, params: { id: 'FAKE_ID', vocab: 'OCLC_FAST' }
419
429
  expect(response.code).to eq('404')
@@ -566,6 +576,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
566
576
  stub_request(:get, 'http://localhost/test_default/term?uri=http://id.worldcat.org/fast/530369').to_return(status: 500)
567
577
  end
568
578
  it 'returns 500' do
579
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
569
580
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term http://id.worldcat.org/fast/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
570
581
  get :fetch, params: { vocab: 'LOD_TERM_URI_PARAM_CONFIG', uri: 'http://id.worldcat.org/fast/530369' }
571
582
  expect(response.code).to eq('500')
@@ -580,6 +591,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
580
591
  it 'returns 500' do
581
592
  msg = "RDF Format Error - Results from fetch term http://id.worldcat.org/fast/530369 for authority LOD_TERM_URI_PARAM_CONFIG was not identified as a valid RDF format. " \
582
593
  "You may need to include the linkeddata gem."
594
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
583
595
  expect(Rails.logger).to receive(:warn).with(msg)
584
596
  get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
585
597
  expect(response.code).to eq('500')
@@ -591,6 +603,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
591
603
  stub_request(:get, 'http://localhost/test_default/term?uri=http://id.worldcat.org/fast/530369').to_return(status: 501)
592
604
  end
593
605
  it 'returns 500' do
606
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
594
607
  expect(Rails.logger).to receive(:warn).with("Internal Server Error - Fetch term http://id.worldcat.org/fast/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
595
608
  get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
596
609
  expect(response.code).to eq('500')
@@ -603,6 +616,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
603
616
  stub_request(:get, 'http://localhost/test_default/term?uri=http://id.worldcat.org/fast/530369').to_return(status: 503)
604
617
  end
605
618
  it 'returns 503' do
619
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
606
620
  expect(Rails.logger).to receive(:warn).with("Service Unavailable - Fetch term http://id.worldcat.org/fast/530369 unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG")
607
621
  get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
608
622
  expect(response.code).to eq('503')
@@ -614,6 +628,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
614
628
  stub_request(:get, 'http://localhost/test_default/term?uri=http://test.org/FAKE_ID').to_return(status: 404, body: '', headers: {})
615
629
  end
616
630
  it 'returns 404' do
631
+ expect(Rails.logger).to receive(:warn).with(graph_load_failure)
617
632
  expect(Rails.logger).to receive(:warn).with('Term Not Found - Fetch term http://test.org/FAKE_ID unsuccessful for authority LOD_TERM_URI_PARAM_CONFIG')
618
633
  get :fetch, params: { uri: 'http://test.org/FAKE_ID', vocab: 'LOD_TERM_URI_PARAM_CONFIG' }
619
634
  expect(response.code).to eq('404')
@@ -2,8 +2,44 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe Qa::LinkedData::RequestHeaderService do
4
4
  let(:request) { double }
5
+ let(:request_id) { 'anID' }
6
+ let(:some_params) { double }
7
+ let(:location) { double }
8
+ let(:fake_ip) { '111.22.33.4444' }
9
+ let(:city) { 'Ithaca' }
10
+ let(:state) { 'New York' }
11
+ let(:country) { 'US' }
12
+ before do
13
+ allow(request).to receive(:request_id).and_return(request_id)
14
+ allow(request).to receive_message_chain(:path_parameters, :[]).with(:action).and_return('search') # rubocop:disable RSpec/MessageChain
15
+ allow(request).to receive(:location).and_return(location)
16
+ allow(request).to receive(:ip).and_return(fake_ip)
17
+ allow(location).to receive(:city).and_return(city)
18
+ allow(location).to receive(:state).and_return(state)
19
+ allow(location).to receive(:country).and_return(country)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ context 'when Qa.config.suppress_ip_data_from_log is true' do
24
+ before { allow(Qa).to receive_message_chain(:config, :suppress_ip_data_from_log).and_return(true) } # rubocop:disable RSpec/MessageChain
25
+ it 'does not include IP info in log message' do
26
+ expect(Rails.logger).to receive(:info).with("******** SEARCH")
27
+ described_class.new(request: request, params: some_params)
28
+ end
29
+ end
30
+
31
+ context 'when Qa.config.suppress_ip_data_from_log is false' do
32
+ before { allow(Qa).to receive_message_chain(:config, :suppress_ip_data_from_log).and_return(false) } # rubocop:disable RSpec/MessageChain
33
+ it 'does include IP info in log message' do
34
+ expect(Rails.logger).to receive(:info).with("******** SEARCH from IP #{fake_ip} in {city: #{city}, state: #{state}, country: #{country}}")
35
+ described_class.new(request: request, params: some_params)
36
+ end
37
+ end
38
+ end
5
39
 
6
40
  describe '#search_header' do
41
+ let(:request_id) { 's1' }
42
+
7
43
  context 'when optional params are defined' do
8
44
  let(:search_params) do
9
45
  {
@@ -20,6 +56,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
20
56
  it 'uses passed in params' do
21
57
  expected_results =
22
58
  {
59
+ request: request,
60
+ request_id: request_id,
23
61
  context: true,
24
62
  performance_data: true,
25
63
  replacements: { 'maxRecords' => '4' },
@@ -37,6 +75,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
37
75
  it 'returns defaults' do
38
76
  expected_results =
39
77
  {
78
+ request: request,
79
+ request_id: request_id,
40
80
  context: false,
41
81
  performance_data: false,
42
82
  replacements: {},
@@ -53,6 +93,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
53
93
  it 'returns defaults with language set to request language' do
54
94
  expected_results =
55
95
  {
96
+ request: request,
97
+ request_id: request_id,
56
98
  context: false,
57
99
  performance_data: false,
58
100
  replacements: {},
@@ -67,6 +109,7 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
67
109
  end
68
110
 
69
111
  describe '#fetch_header' do
112
+ let(:request_id) { 'f1' }
70
113
  context 'when optional params are defined' do
71
114
  let(:fetch_params) do
72
115
  {
@@ -84,6 +127,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
84
127
  it 'uses passed in params' do
85
128
  expected_results =
86
129
  {
130
+ request: request,
131
+ request_id: request_id,
87
132
  format: 'n3',
88
133
  performance_data: true,
89
134
  replacements: { 'extra' => 'data', 'even' => 'more data' },
@@ -101,6 +146,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
101
146
  it 'returns defaults' do
102
147
  expected_results =
103
148
  {
149
+ request: request,
150
+ request_id: request_id,
104
151
  format: 'json',
105
152
  performance_data: false,
106
153
  replacements: {},
@@ -117,6 +164,8 @@ RSpec.describe Qa::LinkedData::RequestHeaderService do
117
164
  it 'returns defaults with language set to request language' do
118
165
  expected_results =
119
166
  {
167
+ request: request,
168
+ request_id: request_id,
120
169
  format: 'json',
121
170
  performance_data: false,
122
171
  replacements: {},
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qa
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Anderson
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2019-12-03 00:00:00.000000000 Z
19
+ date: 2019-12-16 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: activerecord-import
@@ -60,6 +60,20 @@ dependencies:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: geocoder
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
63
77
  - !ruby/object:Gem::Dependency
64
78
  name: ldpath
65
79
  requirement: !ruby/object:Gem::Requirement