ebsco-eds 0.3.5.pre → 0.3.6.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env.test +4 -3
- data/lib/ebsco/eds/configuration.rb +5 -3
- data/lib/ebsco/eds/options.rb +3 -1
- data/lib/ebsco/eds/session.rb +145 -2
- data/lib/ebsco/eds/version.rb +1 -1
- data/lib/faraday/eds_caching_middleware.rb +34 -18
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a58056a9b170977e96d0538c7c656e7d8809cb8d
|
4
|
+
data.tar.gz: 51d4f45f67dfbf40efbf512298053351e6c5e06a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42ffb1d9f4516cd381f4f66e0ffc8c2e89249f9073e966fb3a5467aa26ff3b78e0566ebbcd7835087c98ba83d096e76ba129371b941c07e4a6e5fb4826e82631
|
7
|
+
data.tar.gz: 199c710a0e5d9bf105a53ba800c606531e71e638a4461e71f5c7e138f0906a444102bd783b4acdbf6afde321b7178b4b0c9e13f9f5869ed28e0ac6cc87116eb9
|
data/.env.test
CHANGED
@@ -17,7 +17,7 @@ module EBSCO
|
|
17
17
|
:auth => 'user',
|
18
18
|
:auth_token => '',
|
19
19
|
:session_token => '',
|
20
|
-
:eds_api_base => 'https://eds-api.ebscohost.com',
|
20
|
+
:eds_api_base => 'https://eds-api-b.ebscohost.com',
|
21
21
|
:uid_auth_url => '/authservice/rest/uidauth',
|
22
22
|
:ip_auth_url => '/authservice/rest/ipauth',
|
23
23
|
:create_session_url => '/edsapi/rest/CreateSession',
|
@@ -29,13 +29,15 @@ module EBSCO
|
|
29
29
|
:interface_id => 'edsapi_ruby_gem',
|
30
30
|
:log => 'faraday.log',
|
31
31
|
:log_level => 'INFO',
|
32
|
-
:max_attempts =>
|
32
|
+
:max_attempts => 3,
|
33
33
|
:max_results_per_page => 100,
|
34
34
|
:ebook_preferred_format => 'ebook-pdf',
|
35
35
|
:use_cache => true,
|
36
36
|
:eds_cache_dir => ENV['TMPDIR'] || '/tmp',
|
37
37
|
:timeout => 60,
|
38
|
-
:open_timeout => 12
|
38
|
+
:open_timeout => 12,
|
39
|
+
:max_page_jumps => 6,
|
40
|
+
:max_page_jump_attempts => 10
|
39
41
|
}
|
40
42
|
@valid_config_keys = @config.keys
|
41
43
|
end
|
data/lib/ebsco/eds/options.rb
CHANGED
@@ -6,7 +6,7 @@ module EBSCO
|
|
6
6
|
|
7
7
|
class Options
|
8
8
|
include JSONable
|
9
|
-
attr_accessor :SearchCriteria, :RetrievalCriteria, :Actions
|
9
|
+
attr_accessor :SearchCriteria, :RetrievalCriteria, :Actions, :Comment
|
10
10
|
def initialize(options = {}, info)
|
11
11
|
|
12
12
|
@SearchCriteria = EBSCO::EDS::SearchCriteria.new(options, info)
|
@@ -15,6 +15,8 @@ module EBSCO
|
|
15
15
|
|
16
16
|
@Actions = []
|
17
17
|
|
18
|
+
@Comment = ''
|
19
|
+
|
18
20
|
# add DefaultOn=y Type=select limiters
|
19
21
|
# info.available_limiters.each do |limiter|
|
20
22
|
# if limiter['DefaultOn'] == 'n' and limiter['Type'] == 'select'
|
data/lib/ebsco/eds/session.rb
CHANGED
@@ -70,6 +70,7 @@ module EBSCO
|
|
70
70
|
@auth_token = ''
|
71
71
|
@config = {}
|
72
72
|
@guest = true
|
73
|
+
@api_base = ''
|
73
74
|
|
74
75
|
eds_config = EBSCO::EDS::Configuration.new
|
75
76
|
if options[:config]
|
@@ -129,6 +130,8 @@ module EBSCO
|
|
129
130
|
end :
|
130
131
|
@debug = @config[:debug]
|
131
132
|
|
133
|
+
(ENV.has_key? 'EDS_API_BASE') ? @api_base = ENV['EDS_API_BASE'] : @api_base = @config[:eds_api_base]
|
134
|
+
|
132
135
|
# use cache for auth token, info, search and retrieve calls?
|
133
136
|
if @use_cache
|
134
137
|
cache_dir = File.join(@cache_dir, 'faraday_eds_cache')
|
@@ -720,6 +723,68 @@ module EBSCO
|
|
720
723
|
@auth_token = nil
|
721
724
|
@auth_token = create_auth_token
|
722
725
|
do_request(method, path: path, payload: payload, attempt: attempt+1)
|
726
|
+
|
727
|
+
# trying to paginate in results list beyond 250 results
|
728
|
+
when '138'
|
729
|
+
|
730
|
+
puts 'JUMP ERROR: ' + e.inspect
|
731
|
+
|
732
|
+
is_jump_retry = false
|
733
|
+
is_orig_retry = false
|
734
|
+
|
735
|
+
# create a jump request payload
|
736
|
+
jump_payload = payload.clone
|
737
|
+
|
738
|
+
# retry failed jump requests (known API issue)
|
739
|
+
if jump_payload.instance_variable_defined?(:@Comment)
|
740
|
+
if jump_payload.Comment == 'jump_request'
|
741
|
+
is_jump_retry = true
|
742
|
+
puts '138 JUMP RETRY ================================================================' if @debug
|
743
|
+
sleep Random.new.rand(1..3)
|
744
|
+
do_jump_request(method, path: path, payload: jump_payload, attempt: attempt+1)
|
745
|
+
elsif jump_payload.Comment == 'jump_request_orig'
|
746
|
+
is_orig_retry = true
|
747
|
+
puts '138 ORIG RETRY ================================================================' if @debug
|
748
|
+
sleep Random.new.rand(1..3)
|
749
|
+
jump_response = do_jump_request(method, path: path, payload: payload, attempt: attempt+1)
|
750
|
+
if jump_response.success?
|
751
|
+
return jump_response.body
|
752
|
+
end
|
753
|
+
else
|
754
|
+
puts '138 ERROR =====================================================================' if @debug
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
# only perform these steps if it's the original 138 error
|
759
|
+
unless is_jump_retry or is_orig_retry
|
760
|
+
# remove these variables since they prevent a jump request (they continue to cause more 138 errors)
|
761
|
+
if jump_payload.SearchCriteria.instance_variable_defined?(:@AutoSuggest)
|
762
|
+
jump_payload.SearchCriteria.remove_instance_variable(:@AutoSuggest)
|
763
|
+
end
|
764
|
+
if jump_payload.SearchCriteria.instance_variable_defined?(:@Expanders)
|
765
|
+
jump_payload.SearchCriteria.remove_instance_variable(:@Expanders)
|
766
|
+
end
|
767
|
+
if jump_payload.SearchCriteria.instance_variable_defined?(:@RelatedContent)
|
768
|
+
jump_payload.SearchCriteria.remove_instance_variable(:@RelatedContent)
|
769
|
+
end
|
770
|
+
if jump_payload.SearchCriteria.instance_variable_defined?(:@Limiters)
|
771
|
+
jump_payload.SearchCriteria.remove_instance_variable(:@Limiters)
|
772
|
+
end
|
773
|
+
|
774
|
+
# get list of jump pages and make requests for each one before requesting the original request
|
775
|
+
jump_pages = get_jump_pages(payload)
|
776
|
+
# todo: truncate to @confi[:max_page_jumps]
|
777
|
+
jump_pages.each { |page|
|
778
|
+
jump_payload.Actions = ["GoToPage(#{page})"]
|
779
|
+
jump_payload.Comment = 'jump_request' # comment the request so we can retry if necessary
|
780
|
+
do_jump_request(method, path: path, payload: jump_payload, attempt: attempt+1)
|
781
|
+
}
|
782
|
+
|
783
|
+
# now make the original request (which can also require retries)
|
784
|
+
payload.Comment = 'jump_request_orig'
|
785
|
+
do_request(method, path: path, payload: payload, attempt: attempt+1)
|
786
|
+
end
|
787
|
+
|
723
788
|
# invalid source type, attempt to recover gracefully
|
724
789
|
# when '130'
|
725
790
|
# bad_source_type = e.fault[:error_body]['DetailedErrorDescription']
|
@@ -743,6 +808,8 @@ module EBSCO
|
|
743
808
|
# }
|
744
809
|
# payload.Actions = new_actions
|
745
810
|
# do_request(method, path: path, payload: payload, attempt: attempt+1)
|
811
|
+
|
812
|
+
|
746
813
|
else
|
747
814
|
raise e
|
748
815
|
end
|
@@ -753,6 +820,50 @@ module EBSCO
|
|
753
820
|
end
|
754
821
|
end
|
755
822
|
|
823
|
+
def do_jump_request(method, path:, payload: nil, attempt: 0) # :nodoc:
|
824
|
+
|
825
|
+
if attempt > @config[:max_page_jump_attempts]
|
826
|
+
raise EBSCO::EDS::ApiError, 'EBSCO API error: Multiple attempts to perform request failed.'
|
827
|
+
end
|
828
|
+
begin
|
829
|
+
if @debug
|
830
|
+
if payload.instance_variable_defined?(:@Actions)
|
831
|
+
puts 'JUMP ACTION: ' + payload.Actions.inspect
|
832
|
+
end
|
833
|
+
puts 'JUMP ATTEMPT: ' + attempt.to_s
|
834
|
+
end
|
835
|
+
# turn off caching
|
836
|
+
resp = jump_connection.send(method) do |req|
|
837
|
+
case method
|
838
|
+
when :get
|
839
|
+
req.url path
|
840
|
+
when :post
|
841
|
+
req.url path
|
842
|
+
unless payload.nil?
|
843
|
+
req.body = JSON.generate(payload)
|
844
|
+
end
|
845
|
+
else
|
846
|
+
raise EBSCO::EDS::ApiError, "EBSCO API error: Method #{method} not supported for endpoint #{path}"
|
847
|
+
end
|
848
|
+
end
|
849
|
+
resp
|
850
|
+
rescue Error => e
|
851
|
+
if e.respond_to? 'fault'
|
852
|
+
error_code = e.fault[:error_body]['ErrorNumber'] || e.fault[:error_body]['ErrorCode']
|
853
|
+
unless error_code.nil?
|
854
|
+
case error_code
|
855
|
+
when '138'
|
856
|
+
sleep Random.new.rand(1..3)
|
857
|
+
do_jump_request(method, path: path, payload: payload, attempt: attempt+1)
|
858
|
+
else
|
859
|
+
raise e
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
end
|
865
|
+
end
|
866
|
+
|
756
867
|
# --
|
757
868
|
# attempts to query profile capabilities
|
758
869
|
# dummy search just to get the list of available databases
|
@@ -797,7 +908,7 @@ module EBSCO
|
|
797
908
|
def connection
|
798
909
|
logger = Logger.new(@config[:log])
|
799
910
|
logger.level = Logger.const_get(@config[:log_level])
|
800
|
-
Faraday.new(url: @
|
911
|
+
Faraday.new(url: @api_base) do |conn|
|
801
912
|
conn.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
802
913
|
conn.headers['Accept'] = 'application/json'
|
803
914
|
conn.headers['x-sessionToken'] = @session_token ? @session_token : ''
|
@@ -814,6 +925,26 @@ module EBSCO
|
|
814
925
|
end
|
815
926
|
end
|
816
927
|
|
928
|
+
# same as above but no caching
|
929
|
+
def jump_connection
|
930
|
+
logger = Logger.new(@config[:log])
|
931
|
+
logger.level = Logger.const_get(@config[:log_level])
|
932
|
+
Faraday.new(url: @api_base) do |conn|
|
933
|
+
conn.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
934
|
+
conn.headers['Accept'] = 'application/json'
|
935
|
+
conn.headers['x-sessionToken'] = @session_token ? @session_token : ''
|
936
|
+
conn.headers['x-authenticationToken'] = @auth_token ? @auth_token : ''
|
937
|
+
conn.headers['User-Agent'] = @config[:user_agent]
|
938
|
+
conn.request :url_encoded
|
939
|
+
conn.use :eds_exception_middleware
|
940
|
+
conn.response :json, content_type: /\bjson$/
|
941
|
+
conn.response :detailed_logger, logger if @debug
|
942
|
+
conn.options[:open_timeout] = @config[:open_timeout]
|
943
|
+
conn.options[:timeout] = @config[:timeout]
|
944
|
+
conn.adapter :net_http_persistent
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
817
948
|
def create_auth_token
|
818
949
|
if blank?(@auth_token)
|
819
950
|
# ip auth
|
@@ -895,7 +1026,19 @@ module EBSCO
|
|
895
1026
|
str
|
896
1027
|
end
|
897
1028
|
|
898
|
-
|
1029
|
+
def get_jump_pages(search_options)
|
1030
|
+
dest_page = search_options.RetrievalCriteria.PageNumber.to_i
|
1031
|
+
jump_incr = 250/search_options.RetrievalCriteria.ResultsPerPage.to_i
|
1032
|
+
attempts = dest_page/jump_incr
|
1033
|
+
jump_pages = []
|
1034
|
+
puts 'CURRENT PAGE: ' + @current_page.inspect
|
1035
|
+
(1..attempts).to_a.each do |n|
|
1036
|
+
jump_pages.push(jump_incr*n)
|
1037
|
+
end
|
1038
|
+
puts 'JUMP PAGES: ' + jump_pages.inspect if @debug
|
1039
|
+
jump_pages
|
1040
|
+
end
|
899
1041
|
|
1042
|
+
end
|
900
1043
|
end
|
901
1044
|
end
|
data/lib/ebsco/eds/version.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'uri'
|
3
|
+
require 'ebsco/eds/configuration'
|
3
4
|
|
4
5
|
module Faraday
|
5
6
|
|
6
7
|
class EdsCachingMiddleware < Faraday::Middleware
|
7
8
|
|
8
|
-
INFO_URI = URI.parse('https://eds-api.ebscohost.com/edsapi/rest/Info')
|
9
|
-
AUTH_URI = URI.parse('https://eds-api.ebscohost.com/authservice/rest/uidauth')
|
10
|
-
SEARCH_URI = URI.parse('https://eds-api.ebscohost.com/edsapi/rest/Search?')
|
11
|
-
RETRIEVE_URI = URI.parse('https://eds-api.ebscohost.com/edsapi/rest/Retrieve?')
|
12
|
-
|
13
9
|
def initialize(app, *args)
|
14
10
|
super(app)
|
15
11
|
options = args.first || {}
|
@@ -22,6 +18,21 @@ module Faraday
|
|
22
18
|
@store_options[:namespace] ||= @namespace
|
23
19
|
|
24
20
|
initialize_store
|
21
|
+
|
22
|
+
eds_config = EBSCO::EDS::Configuration.new
|
23
|
+
if options[:config]
|
24
|
+
@config = eds_config.configure_with(options[:config])
|
25
|
+
@config = eds_config.configure if @config.nil?
|
26
|
+
else
|
27
|
+
@config = eds_config.configure(options)
|
28
|
+
end
|
29
|
+
(ENV.has_key? 'EDS_API_BASE') ? @api_base = ENV['EDS_API_BASE'] : @api_base = @config[:eds_api_base]
|
30
|
+
|
31
|
+
@info_uri = URI.parse(@api_base + '/edsapi/rest/Info')
|
32
|
+
@auth_uri = URI.parse(@api_base + '/authservice/rest/uidauth')
|
33
|
+
@search_uri = URI.parse(@api_base + '/edsapi/rest/Search?')
|
34
|
+
@retrieve_uri = URI.parse(@api_base + '/edsapi/rest/Retrieve?')
|
35
|
+
|
25
36
|
end
|
26
37
|
|
27
38
|
def call(env)
|
@@ -48,26 +59,26 @@ module Faraday
|
|
48
59
|
#puts 'ENV: ' + env.inspect
|
49
60
|
return unless cacheable?(env) && !env.request_headers['x-faraday-eds-cache']
|
50
61
|
|
51
|
-
|
62
|
+
puts "Cache WRITE: #{key(env)}"
|
52
63
|
custom_expires_in = @expires_in
|
53
64
|
uri = env.url
|
54
65
|
|
55
|
-
if uri ==
|
66
|
+
if uri == @auth_uri
|
56
67
|
custom_expires_in = 1800 # 30 minutes
|
57
68
|
info "#{uri} - Setting custom expires: #{custom_expires_in}"
|
58
69
|
end
|
59
70
|
|
60
|
-
if uri ==
|
71
|
+
if uri == @info_uri
|
61
72
|
custom_expires_in = 86400 # 24 hours
|
62
73
|
info "#{uri} - Setting custom expires: #{custom_expires_in}"
|
63
74
|
end
|
64
75
|
|
65
|
-
if uri.request_uri.start_with?(
|
76
|
+
if uri.request_uri.start_with?(@search_uri.request_uri)
|
66
77
|
custom_expires_in = 1800 # 30 minutes
|
67
78
|
info "#{uri} - Setting custom expires: #{custom_expires_in}"
|
68
79
|
end
|
69
80
|
|
70
|
-
if uri.request_uri.start_with?(
|
81
|
+
if uri.request_uri.start_with?(@retrieve_uri.request_uri)
|
71
82
|
custom_expires_in = 1800 # 30 minutes
|
72
83
|
info "#{uri} - Setting custom expires: #{custom_expires_in}"
|
73
84
|
end
|
@@ -77,13 +88,18 @@ module Faraday
|
|
77
88
|
|
78
89
|
def cacheable?(env)
|
79
90
|
uri = env.url
|
80
|
-
if uri ==
|
81
|
-
uri.request_uri.start_with?(
|
82
|
-
uri.request_uri.start_with?(
|
83
|
-
|
84
|
-
|
91
|
+
if uri == @auth_uri || uri == @info_uri ||
|
92
|
+
uri.request_uri.start_with?(@search_uri.request_uri) ||
|
93
|
+
uri.request_uri.start_with?(@retrieve_uri.request_uri)
|
94
|
+
if !env.body.nil? && env.body.include?('"jump_request"')
|
95
|
+
puts "NOT CACHEABLE URI (jump_request): #{uri}"
|
96
|
+
false
|
97
|
+
else
|
98
|
+
puts "CACHEABLE URI: #{uri}"
|
99
|
+
true
|
100
|
+
end
|
85
101
|
else
|
86
|
-
|
102
|
+
puts "NOT CACHEABLE URI: #{uri}"
|
87
103
|
false
|
88
104
|
end
|
89
105
|
end
|
@@ -95,9 +111,9 @@ module Faraday
|
|
95
111
|
end
|
96
112
|
|
97
113
|
if response_env
|
98
|
-
|
114
|
+
puts "Cache HIT: #{key(env)}"
|
99
115
|
else
|
100
|
-
|
116
|
+
puts "Cache MISS: #{key(env)}"
|
101
117
|
end
|
102
118
|
response_env
|
103
119
|
end
|