kpm 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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