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 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