kpm 0.8.2 → 0.9.0

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +73 -8
  4. data/README.adoc +15 -0
  5. data/kpm.gemspec +3 -3
  6. data/lib/kpm/account.rb +3 -2
  7. data/lib/kpm/coordinates.rb +4 -3
  8. data/lib/kpm/database.rb +3 -2
  9. data/lib/kpm/formatter.rb +2 -2
  10. data/lib/kpm/inspector.rb +2 -2
  11. data/lib/kpm/migrations.rb +18 -4
  12. data/lib/kpm/nexus_helper/actions.rb +2 -5
  13. data/lib/kpm/nexus_helper/github_api_calls.rb +70 -0
  14. data/lib/kpm/nexus_helper/nexus_api_calls_v2.rb +79 -50
  15. data/lib/kpm/tasks.rb +3 -3
  16. data/lib/kpm/tenant_config.rb +1 -1
  17. data/lib/kpm/tomcat_manager.rb +1 -0
  18. data/lib/kpm/version.rb +1 -1
  19. data/pom.xml +1 -1
  20. data/spec/kpm/remote/base_artifact_spec.rb +15 -13
  21. data/spec/kpm/remote/base_installer_spec.rb +13 -13
  22. data/spec/kpm/remote/github_api_calls_spec.rb +40 -0
  23. data/spec/kpm/remote/installer_spec.rb +30 -30
  24. data/spec/kpm/remote/kaui_artifact_spec.rb +4 -4
  25. data/spec/kpm/remote/killbill_plugin_artifact_spec.rb +19 -19
  26. data/spec/kpm/remote/killbill_server_artifact_spec.rb +13 -13
  27. data/spec/kpm/remote/migrations_spec.rb +9 -9
  28. data/spec/kpm/remote/nexus_facade_spec.rb +2 -2
  29. data/spec/kpm/remote/tenant_config_spec.rb +3 -3
  30. data/spec/kpm/remote/tomcat_manager_spec.rb +2 -2
  31. data/spec/kpm/unit/actions_spec.rb +2 -2
  32. data/spec/kpm/unit/base_artifact_spec.rb +14 -14
  33. data/spec/kpm/unit/inspector_spec.rb +28 -28
  34. data/spec/kpm/unit/installer_spec.rb +4 -4
  35. data/spec/kpm/unit/plugins_directory_spec.rb +31 -31
  36. data/spec/kpm/unit/plugins_manager_spec.rb +54 -54
  37. data/spec/kpm/unit/sha1_checker_spec.rb +2 -2
  38. data/spec/kpm/unit/uninstaller_spec.rb +21 -21
  39. data/spec/kpm/unit_mysql/account_spec.rb +13 -13
  40. data/spec/spec_helper.rb +1 -1
  41. metadata +10 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df289be332b4f05a4bbef990e189e237d7abef620b4f2318c3e2baadef91d6ce
4
- data.tar.gz: d07e97f59cf97689ee44a5a6bcd1d9474765432db76fdafb47f999c9d6c10b50
3
+ metadata.gz: 0d40f3a357b1d6291000edb471a0af5f097d60b87befd5fe81c24b7c7d06eaab
4
+ data.tar.gz: c20904d06ada1b9a6ee9efaeeae4c1ec1701922a6ad862a207ee5ff76ac3274e
5
5
  SHA512:
6
- metadata.gz: 80003066d5993ad352c661061c68282f128c52c975b2d9d027b8d0aa177629646e0c6789d3bbdd585ea4393713474f817fb09ae9faa48d7ddbb68eb5d87fc812
7
- data.tar.gz: d1e570789b7d818606df5e5072183e4c76d2ad807bc0ed5ca2aeac0fc68769fe3b11081babd56623efaca7109954b504961e5fecf20047c9cb59e47e72b51832
6
+ metadata.gz: 2734efed5f46394d5109a9389f419a639d09f3967b6f52a5566bda9d1e5a21009a19576e8fc9887fe003372a33a947a8c21d03becc733f4f3409df4d174a36f6
7
+ data.tar.gz: 0e30885e28fd2614aa0fb31f76927410816d576c386009f634c2716b17575ae755beb0746d53a914f7b2b2073f592e294a3fd500eb0c612f5b62ec5f483ae20c
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ kpm-*-linux-x86_64.tar.gz
7
7
  kpm-*-osx.tar.gz
8
8
  traveling-ruby-*.tar.gz
9
9
  *.asc
10
+ .rakeTasks
@@ -4,6 +4,15 @@
4
4
  Gemspec/RequiredRubyVersion:
5
5
  Enabled: false
6
6
 
7
+ Layout/LineLength:
8
+ Enabled: false
9
+
10
+ Layout/EmptyLinesAroundAttributeAccessor:
11
+ Enabled: true
12
+
13
+ Layout/SpaceAroundMethodCallOperator:
14
+ Enabled: true
15
+
7
16
  # Alternative?
8
17
  Gemspec/RubyVersionGlobalsUsage:
9
18
  Enabled: false
@@ -11,7 +20,22 @@ Gemspec/RubyVersionGlobalsUsage:
11
20
  Layout/DefEndAlignment:
12
21
  AutoCorrect: true
13
22
 
14
- Lint/HandleExceptions:
23
+ Lint/DeprecatedOpenSSLConstant:
24
+ Enabled: true
25
+
26
+ Lint/DuplicateElsifCondition:
27
+ Enabled: true
28
+
29
+ Lint/MixedRegexpCaptureTypes:
30
+ Enabled: true
31
+
32
+ Lint/RaiseException:
33
+ Enabled: true
34
+
35
+ Lint/StructNewOverride:
36
+ Enabled: true
37
+
38
+ Lint/SuppressedException:
15
39
  AllowComments: true
16
40
 
17
41
  Metrics/AbcSize:
@@ -29,9 +53,6 @@ Metrics/ClassLength:
29
53
  Metrics/CyclomaticComplexity:
30
54
  Enabled: false
31
55
 
32
- Metrics/LineLength:
33
- Enabled: false
34
-
35
56
  Metrics/MethodLength:
36
57
  Enabled: false
37
58
 
@@ -47,10 +68,6 @@ Metrics/PerceivedComplexity:
47
68
  Security/YAMLLoad:
48
69
  Enabled: false
49
70
 
50
- # We must support old Rubies
51
- Style/BracesAroundHashParameters:
52
- Enabled: false
53
-
54
71
  Style/Documentation:
55
72
  Enabled: false
56
73
 
@@ -71,3 +88,51 @@ Style/SafeNavigation:
71
88
 
72
89
  Style/GuardClause:
73
90
  Enabled: false
91
+
92
+ Style/AccessorGrouping:
93
+ Enabled: true
94
+
95
+ Style/ArrayCoercion:
96
+ Enabled: true
97
+
98
+ Style/BisectedAttrAccessor:
99
+ Enabled: true
100
+
101
+ Style/CaseLikeIf:
102
+ Enabled: true
103
+
104
+ Style/ExponentialNotation:
105
+ Enabled: true
106
+
107
+ Style/HashAsLastArrayItem:
108
+ Enabled: true
109
+
110
+ Style/HashEachMethods:
111
+ Enabled: true
112
+
113
+ Style/HashLikeCase:
114
+ Enabled: true
115
+
116
+ Style/HashTransformKeys:
117
+ Enabled: true
118
+
119
+ Style/HashTransformValues:
120
+ Enabled: true
121
+
122
+ Style/RedundantAssignment:
123
+ Enabled: true
124
+
125
+ Style/RedundantFetchBlock:
126
+ Enabled: true
127
+
128
+ Style/RedundantFileExtensionInRequire:
129
+ Enabled: true
130
+
131
+ Style/RedundantRegexpCharacterClass:
132
+ Enabled: true
133
+
134
+ Style/RedundantRegexpEscape:
135
+ Enabled: true
136
+
137
+ Style/SlicingWithRange:
138
+ Enabled: true
@@ -245,3 +245,18 @@ Notes:
245
245
 
246
246
  * You can override that behavior with the `--force-download` switch
247
247
  * When `--force-download` is specified (`false` by default), network access to a Nexus instance is required. Otherwise, downloads are idempotent even if no outbound networking is allowed (on initial download, the Nexus metadata is cached in the `sha1.yml` file which is re-used on subsequent installation if no outbound networking is allowed -- by default, KPM will try to get the latest metadata from Nexus though)
248
+
249
+ [[gh-packages]]
250
+ ### GitHub Packages
251
+
252
+ KPM was initially designed to work against Sonatype. Starting with version 0.9.0, experimental support for GitHub packages has been added:
253
+
254
+ ....
255
+ kpm install_java_plugin acme:plugin \
256
+ --overrides url:https://maven.pkg.github.com/acme/plugin token:<TOKEN> \
257
+ --group-id com.acme \
258
+ --artifact-id plugin \
259
+ --version 0.0.1
260
+ ....
261
+
262
+ Replace `TOKEN` with a GitHub personal access token.
@@ -46,7 +46,7 @@ Gem::Specification.new do |s|
46
46
  s.add_dependency 'rubyzip', '~>1.2.0'
47
47
  s.add_dependency 'thor', '~> 0.19.1'
48
48
 
49
- s.add_development_dependency 'rake', '>= 10.0.0', '< 11.0.0'
50
- s.add_development_dependency 'rspec', '~> 2.12.0'
51
- s.add_development_dependency 'rubocop', '~> 0.74.0' if RUBY_VERSION >= '2.3'
49
+ s.add_development_dependency 'rake', '~> 13.0'
50
+ s.add_development_dependency 'rspec', '~> 3.9'
51
+ s.add_development_dependency 'rubocop', '~> 0.88.0' if RUBY_VERSION >= '2.4'
52
52
  end
@@ -316,9 +316,10 @@ module KPM
316
316
  end
317
317
 
318
318
  def replace_boolean(value)
319
- if value.to_s == 'true'
319
+ case value.to_s
320
+ when 'true'
320
321
  1
321
- elsif value.to_s == 'false'
322
+ when 'false'
322
323
  0
323
324
  else
324
325
  value
@@ -24,11 +24,12 @@ module KPM
24
24
  def get_coordinate_map(entry)
25
25
  parts = entry.split(':')
26
26
  length = parts.size
27
- if length == 3
27
+ case length
28
+ when 3
28
29
  { group_id: parts[0], artifact_id: parts[1], packaging: parts[2] }
29
- elsif length == 4
30
+ when 4
30
31
  { group_id: parts[0], artifact_id: parts[1], packaging: parts[2], version: parts[3] }
31
- elsif length == 5
32
+ when 5
32
33
  { group_id: parts[0], artifact_id: parts[1], packaging: parts[2], classifier: parts[3], version: parts[4] }
33
34
  end
34
35
  end
@@ -86,9 +86,10 @@ module KPM
86
86
  rows = []
87
87
  table[:rows].each do |row|
88
88
  rows << row.map do |value|
89
- if value.is_a?(Symbol)
89
+ case value
90
+ when Symbol
90
91
  value.to_s
91
- elsif value.is_a?(Blob)
92
+ when Blob
92
93
  value.value
93
94
  else
94
95
  escaped_value = value.to_s.gsub(/['"]/, "'" => "\\'", '"' => '\\"')
@@ -97,7 +97,7 @@ module KPM
97
97
  formatted += Kernel.format("#{format_string}\n", *labels_format_argument)
98
98
  formatted += "#{border}\n"
99
99
 
100
- data.keys.each do |key|
100
+ data.each_key do |key|
101
101
  v = data[key]
102
102
 
103
103
  arguments = []
@@ -131,7 +131,7 @@ module KPM
131
131
  seen_labels = Set.new
132
132
 
133
133
  labels_format_argument = []
134
- data.keys.each do |key|
134
+ data.each_key do |key|
135
135
  v = data[key]
136
136
  labels.each do |e|
137
137
  # sanitize entry at the same time
@@ -33,7 +33,7 @@ module KPM
33
33
  sha1_file = "#{bundles_dir}/#{sha1_filename}"
34
34
  sha1_checker = Sha1Checker.from_file(sha1_file)
35
35
 
36
- all_plugins.keys.each do |cur_plugin_name|
36
+ all_plugins.each_key do |cur_plugin_name|
37
37
  cur = all_plugins[cur_plugin_name]
38
38
 
39
39
  sha1_checker.all_sha1.each do |e|
@@ -52,7 +52,7 @@ module KPM
52
52
 
53
53
  def add_plugin_identifier_info(plugins, all_plugins)
54
54
  plugins_manager = PluginsManager.new(plugins, @logger)
55
- all_plugins.keys.each do |cur|
55
+ all_plugins.each_key do |cur|
56
56
  plugin_key, entry = plugins_manager.get_identifier_key_and_entry(cur)
57
57
  all_plugins[cur][:plugin_key] = plugin_key
58
58
  all_plugins[cur][:group_id] = entry ? entry['group_id'] : nil
@@ -54,7 +54,7 @@ module KPM
54
54
 
55
55
  def for_version(version = @from_version, name_only = false, migrations_to_skip = Set.new)
56
56
  @logger.info("Looking for migrations repository=#{@repository}, version=#{version}")
57
- metadata = get_as_json("https://api.github.com/repos/#{@repository}/git/trees/#{version}?recursive=1&access_token=#{@oauth_token}")
57
+ metadata = get_as_json("https://api.github.com/repos/#{@repository}/git/trees/#{version}?recursive=1")
58
58
 
59
59
  migrations = []
60
60
  metadata['tree'].each do |entry|
@@ -67,7 +67,7 @@ module KPM
67
67
 
68
68
  sql = nil
69
69
  unless name_only
70
- blob_metadata = get_as_json("#{entry['url']}?access_token=#{@oauth_token}")
70
+ blob_metadata = get_as_json((entry['url']).to_s)
71
71
  sql = decode(blob_metadata['content'], blob_metadata['encoding'])
72
72
  end
73
73
 
@@ -81,8 +81,22 @@ module KPM
81
81
  end
82
82
 
83
83
  def get_as_json(url)
84
- raw = URI.parse(url).read
85
- JSON.parse(raw)
84
+ uri = URI.parse(url)
85
+ http = Net::HTTP.new(uri.host, uri.port)
86
+ http.use_ssl = uri.scheme == 'https'
87
+
88
+ path = uri.path || '/'
89
+ path = "#{path}?#{uri.query}" unless uri.query.nil?
90
+ request = Net::HTTP::Get.new(path)
91
+ request['Authorization'] = "token #{@oauth_token}" unless @oauth_token.nil?
92
+
93
+ response = http.request(request)
94
+ case response.code
95
+ when '200'
96
+ JSON.parse(response.body)
97
+ else
98
+ raise "Unable to download #{url}: #{response.code}"
99
+ end
86
100
  end
87
101
 
88
102
  def decode(content, encoding)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'nexus_api_calls_v2'
4
- # require_relative 'nexus_api_calls_v3'
4
+ require_relative 'github_api_calls'
5
5
 
6
6
  module KPM
7
7
  module NexusFacade
@@ -29,10 +29,7 @@ module KPM
29
29
 
30
30
  @logger = logger
31
31
 
32
- # this is where the version is verified
33
- # example if
34
- # @nexus_api_call = overrides['version'] == '3' ? NexusApiCallsV3.new(overrides, ssl_verify) : NexusApiCallsV2.new(overrides, ssl_verify)
35
- @nexus_api_call = NexusApiCallsV2.new(overrides, ssl_verify, logger)
32
+ @nexus_api_call = overrides[:url].start_with?('https://maven.pkg.github.com') ? GithubApiCalls.new(overrides, ssl_verify, logger) : NexusApiCallsV2.new(overrides, ssl_verify, logger)
36
33
  end
37
34
 
38
35
  def pull_artifact(coordinates, destination = nil)
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'rexml/document'
6
+ require 'openssl'
7
+
8
+ module KPM
9
+ module NexusFacade
10
+ class GithubApiCalls < NexusApiCallsV2
11
+ def pull_artifact_endpoint(coordinates)
12
+ base_path, versioned_artifact, = build_base_path_and_coords(coordinates)
13
+ "#{base_path}/#{versioned_artifact}"
14
+ end
15
+
16
+ def get_artifact_info(coordinates)
17
+ super
18
+
19
+ _, versioned_artifact, coords = build_base_path_and_coords(coordinates)
20
+ sha1 = get_sha1(coordinates)
21
+ "<artifact-resolution>
22
+ <data>
23
+ <presentLocally>true</presentLocally>
24
+ <groupId>#{coords[:group_id]}</groupId>
25
+ <artifactId>#{coords[:artifact_id]}</artifactId>
26
+ <version>#{coords[:version]}</version>
27
+ <extension>#{coords[:packaging]}</extension>
28
+ <snapshot>#{!(coords[:version] =~ /-SNAPSHOT$/).nil?}</snapshot>
29
+ <sha1>#{sha1}</sha1>
30
+ <repositoryPath>/#{coords[:group_id].gsub('.', '/')}/#{versioned_artifact}</repositoryPath>
31
+ </data>
32
+ </artifact-resolution>"
33
+ end
34
+
35
+ def get_artifact_info_endpoint(coordinates)
36
+ base_path, = build_base_path_and_coords(coordinates)
37
+ "#{base_path}/maven-metadata.xml"
38
+ end
39
+
40
+ def search_for_artifact_endpoint(_coordinates)
41
+ raise NoMethodError, 'GitHub Packages has no search support'
42
+ end
43
+
44
+ def build_query_params(_coordinates, _what_parameters = nil)
45
+ ''
46
+ end
47
+
48
+ private
49
+
50
+ def get_sha1(coordinates)
51
+ base_path, versioned_artifact, = build_base_path_and_coords(coordinates)
52
+ endpoint = "#{base_path}/#{versioned_artifact}.sha1"
53
+ get_response_with_retries(coordinates, endpoint, nil)
54
+ end
55
+
56
+ def build_base_path_and_coords(coordinates)
57
+ coords = parse_coordinates(coordinates)
58
+
59
+ # The url may contain the org and repo, e.g. 'https://maven.pkg.github.com/killbill/qualpay-java-client'
60
+ org_and_repo = URI.parse(configuration[:url]).path
61
+
62
+ [
63
+ "#{org_and_repo}/#{coords[:group_id].gsub('.', '/')}/#{coords[:artifact_id]}",
64
+ "#{coords[:version]}/#{coords[:artifact_id]}-#{coords[:version]}.#{coords[:extension]}",
65
+ coords
66
+ ]
67
+ end
68
+ end
69
+ end
70
+ end
@@ -27,18 +27,13 @@ module KPM
27
27
 
28
28
  # This is an extract and slim down of functions needed from nexus_cli to maintain the response expected by the base_artifact.
29
29
  class NexusApiCallsV2
30
- PULL_ARTIFACT_ENDPOINT = '/service/local/artifact/maven/redirect'
31
- GET_ARTIFACT_INFO_ENDPOINT = '/service/local/artifact/maven/resolve'
32
- SEARCH_FOR_ARTIFACT_ENDPOINT = '/service/local/lucene/search'
33
-
34
30
  READ_TIMEOUT_DEFAULT = 60
35
31
  OPEN_TIMEOUT_DEFAULT = 60
36
32
 
37
33
  ERROR_MESSAGE_404 = 'The artifact you requested information for could not be found. Please ensure it exists inside the Nexus.'
38
34
 
39
- attr_reader :version
40
- attr_reader :configuration
41
- attr_reader :ssl_verify
35
+ attr_reader :version, :configuration, :ssl_verify
36
+
42
37
  attr_accessor :logger
43
38
 
44
39
  def initialize(configuration, ssl_verify, logger)
@@ -49,12 +44,12 @@ module KPM
49
44
 
50
45
  def search_for_artifacts(coordinates)
51
46
  logger.debug "Entered - Search for artifact, coordinates: #{coordinates}"
52
- response = get_response(coordinates, SEARCH_FOR_ARTIFACT_ENDPOINT, %i[g a])
47
+ response = get_response(coordinates, search_for_artifact_endpoint(coordinates), %i[g a])
53
48
 
54
49
  case response.code
55
50
  when '200'
56
51
  logger.debug "response body: #{response.body}"
57
- return response.body
52
+ response.body
58
53
  when '404'
59
54
  raise StandardError, ERROR_MESSAGE_404
60
55
  else
@@ -63,41 +58,18 @@ module KPM
63
58
  end
64
59
 
65
60
  def get_artifact_info(coordinates)
66
- logger.debug "Entered - Get artifact info, coordinates: #{coordinates}"
67
- response = get_response(coordinates, GET_ARTIFACT_INFO_ENDPOINT, nil)
68
-
69
- case response.code
70
- when '200'
71
- logger.debug "response body: #{response.body}"
72
- return response.body
73
- when '404'
74
- raise StandardError, ERROR_MESSAGE_404
75
- else
76
- raise UnexpectedStatusCodeException, response.code
77
- end
61
+ get_response_with_retries(coordinates, get_artifact_info_endpoint(coordinates), nil)
78
62
  end
79
63
 
80
64
  def pull_artifact(coordinates, destination)
81
- logger.debug "Entered - Pull artifact, coordinates: #{coordinates}"
82
65
  file_name = get_file_name(coordinates)
83
66
  destination = File.join(File.expand_path(destination || '.'), file_name)
84
- logger.debug "destination: #{destination}"
85
- response = get_response(coordinates, PULL_ARTIFACT_ENDPOINT, nil)
86
-
87
- case response.code
88
- when '301', '307'
89
- location = response['Location'].gsub!(configuration[:url], '')
90
- logger.debug 'fetching artifact'
91
- file_response = get_response(nil, location, nil)
67
+ logger.debug { "Downloading to destination: #{destination}" }
92
68
 
93
- File.open(destination, 'wb') do |io|
94
- io.write(file_response.body)
95
- end
96
- when 404
97
- raise StandardError, ERROR_MESSAGE_404
98
- else
99
- raise UnexpectedStatusCodeException, response.code
69
+ File.open(destination, 'wb') do |io|
70
+ io.write(get_response_with_retries(coordinates, pull_artifact_endpoint(coordinates), nil))
100
71
  end
72
+
101
73
  {
102
74
  file_name: file_name,
103
75
  file_path: File.expand_path(destination),
@@ -106,6 +78,31 @@ module KPM
106
78
  }
107
79
  end
108
80
 
81
+ def pull_artifact_endpoint(_coordinates)
82
+ '/service/local/artifact/maven/redirect'
83
+ end
84
+
85
+ def get_artifact_info_endpoint(_coordinates)
86
+ '/service/local/artifact/maven/resolve'
87
+ end
88
+
89
+ def search_for_artifact_endpoint(_coordinates)
90
+ '/service/local/lucene/search'
91
+ end
92
+
93
+ def build_query_params(coordinates, what_parameters = nil)
94
+ artifact = parse_coordinates(coordinates)
95
+ @version = artifact[:version].to_s.upcase
96
+
97
+ query = { g: artifact[:group_id], a: artifact[:artifact_id], e: artifact[:extension], v: version, r: configuration[:repository] }
98
+ query.merge!(c: artifact[:classifier]) unless artifact[:classifier].nil?
99
+
100
+ params = what_parameters.nil? ? query : {}
101
+ what_parameters.each { |key| params[key] = query[key] unless query[key].nil? } unless what_parameters.nil?
102
+
103
+ params.map { |key, value| "#{key}=#{value}" }.join('&')
104
+ end
105
+
109
106
  private
110
107
 
111
108
  def parse_coordinates(coordinates)
@@ -139,17 +136,33 @@ module KPM
139
136
  end
140
137
  end
141
138
 
142
- def build_query_params(coordinates, what_parameters = nil)
143
- artifact = parse_coordinates(coordinates)
144
- @version = artifact[:version].to_s.upcase
145
-
146
- query = { g: artifact[:group_id], a: artifact[:artifact_id], e: artifact[:extension], v: version, r: configuration[:repository] }
147
- query.merge!(c: artifact[:classifier]) unless artifact[:classifier].nil?
148
-
149
- params = what_parameters.nil? ? query : {}
150
- what_parameters.each { |key| params[key] = query[key] unless query[key].nil? } unless what_parameters.nil?
139
+ def get_response_with_retries(coordinates, endpoint, what_parameters)
140
+ logger.debug { "Fetching coordinates=#{coordinates}, endpoint=#{endpoint}, params=#{what_parameters}" }
141
+ response = get_response(coordinates, endpoint, what_parameters)
142
+ logger.debug { "Response body: #{response.body}" }
143
+ process_response_with_retries(response)
144
+ end
151
145
 
152
- params.map { |key, value| "#{key}=#{value}" }.join('&')
146
+ def process_response_with_retries(response)
147
+ case response.code
148
+ when '200'
149
+ response.body
150
+ when '301', '307'
151
+ location = response['Location']
152
+ logger.debug { "Following redirect to #{location}" }
153
+
154
+ new_path = location.gsub!(configuration[:url], '')
155
+ if new_path.nil?
156
+ # Redirect to another domain (e.g. CDN)
157
+ get_raw_response_with_retries(location)
158
+ else
159
+ get_response_with_retries(nil, location, nil)
160
+ end
161
+ when '404'
162
+ raise StandardError, ERROR_MESSAGE_404
163
+ else
164
+ raise UnexpectedStatusCodeException, response.code
165
+ end
153
166
  end
154
167
 
155
168
  def get_response(coordinates, endpoint, what_parameters)
@@ -157,11 +170,18 @@ module KPM
157
170
  query_params = build_query_params(coordinates, what_parameters) unless coordinates.nil?
158
171
  endpoint = endpoint_with_params(endpoint, query_params) unless coordinates.nil?
159
172
  request = Net::HTTP::Get.new(endpoint)
173
+ if configuration.key?(:username) && configuration.key?(:password)
174
+ request.basic_auth(configuration[:username], configuration[:password])
175
+ elsif configuration.key?(:token)
176
+ request['Authorization'] = "token #{configuration[:token]}"
177
+ end
160
178
 
161
- logger.debug "request endpoint: #{endpoint}"
179
+ logger.debug do
180
+ http.set_debug_output(logger)
181
+ "HTTP path: #{endpoint}"
182
+ end
162
183
 
163
- response = http.request(request)
164
- response
184
+ http.request(request)
165
185
  end
166
186
 
167
187
  def build_http
@@ -171,9 +191,18 @@ module KPM
171
191
  http.read_timeout = configuration[:read_timeout] || READ_TIMEOUT_DEFAULT # seconds
172
192
  http.use_ssl = (ssl_verify != false)
173
193
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
194
+
195
+ logger.debug { "HTTP connection: #{http.inspect}" }
196
+
174
197
  http
175
198
  end
176
199
 
200
+ def get_raw_response_with_retries(location)
201
+ response = Net::HTTP.get_response(URI(location))
202
+ logger.debug { "Response body: #{response.body}" }
203
+ process_response_with_retries(response)
204
+ end
205
+
177
206
  def endpoint_with_params(endpoint, query_params)
178
207
  "#{endpoint}?#{URI::DEFAULT_PARSER.escape(query_params)}"
179
208
  end