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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b01d52fab1ebf5ad7dff691dc253ae50fef72e97
4
- data.tar.gz: ce5af9c7d9ad9a251964b555518a170d8319f226
3
+ metadata.gz: a58056a9b170977e96d0538c7c656e7d8809cb8d
4
+ data.tar.gz: 51d4f45f67dfbf40efbf512298053351e6c5e06a
5
5
  SHA512:
6
- metadata.gz: 79d7be540a8d86ad94311655d3dd132cd4d39cc34f98241cc9a0284725f4ba0c38681ab5fe062be3bd059c721dad704ef896fa214502ed2bfe385b29c7c22b07
7
- data.tar.gz: c21bddfbcca4af8ee6e7a1b4f914fdca7cf1f201454d145d74693baf81006a6f19114521c75ac9fb1c55ff2878875d685004496e6cfb8bf81ca6d1989a817aa6
6
+ metadata.gz: 42ffb1d9f4516cd381f4f66e0ffc8c2e89249f9073e966fb3a5467aa26ff3b78e0566ebbcd7835087c98ba83d096e76ba129371b941c07e4a6e5fb4826e82631
7
+ data.tar.gz: 199c710a0e5d9bf105a53ba800c606531e71e638a4461e71f5c7e138f0906a444102bd783b4acdbf6afde321b7178b4b0c9e13f9f5869ed28e0ac6cc87116eb9
data/.env.test CHANGED
@@ -1,6 +1,7 @@
1
1
  EDS_PROFILE=edsapi
2
- EDS_USER=user
3
- EDS_PASS=secret
2
+ EDS_USER=stanford
3
+ EDS_PASS=trial
4
4
  EDS_AUTH=user
5
5
  EDS_GUEST=n
6
- EDS_ORG=none
6
+ EDS_ORG=none
7
+ EDS_DEBUG=false
@@ -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 => 2,
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
@@ -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'
@@ -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: @config[:eds_api_base]) do |conn|
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
- end
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
@@ -1,5 +1,5 @@
1
1
  module EBSCO
2
2
  module EDS
3
- VERSION = '0.3.5.pre'
3
+ VERSION = '0.3.6.pre'
4
4
  end
5
5
  end
@@ -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
- info "Cache WRITE: #{key(env)}"
62
+ puts "Cache WRITE: #{key(env)}"
52
63
  custom_expires_in = @expires_in
53
64
  uri = env.url
54
65
 
55
- if uri == AUTH_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 == INFO_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?(SEARCH_URI.request_uri)
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?(RETRIEVE_URI.request_uri)
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 == AUTH_URI || uri == INFO_URI ||
81
- uri.request_uri.start_with?(SEARCH_URI.request_uri) ||
82
- uri.request_uri.start_with?(RETRIEVE_URI.request_uri)
83
- info "CACHEABLE URI: #{uri}"
84
- true
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
- info "NOT CACHEABLE URI: #{uri}"
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
- info "Cache HIT: #{key(env)}"
114
+ puts "Cache HIT: #{key(env)}"
99
115
  else
100
- info "Cache MISS: #{key(env)}"
116
+ puts "Cache MISS: #{key(env)}"
101
117
  end
102
118
  response_env
103
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ebsco-eds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5.pre
4
+ version: 0.3.6.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bill McKinney