ebsco-eds 0.3.5.pre → 0.3.6.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|