2021-01-03 14:25:43 +05:30
# frozen_string_literal: true
2021-01-29 00:20:46 +05:30
module BulkImports
module Clients
2021-09-04 01:27:46 +05:30
class HTTP
2021-11-18 22:05:49 +05:30
include Gitlab :: Utils :: StrongMemoize
2021-04-29 21:17:54 +05:30
API_VERSION = 'v4'
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 30
2021-01-03 14:25:43 +05:30
2021-09-30 23:02:18 +05:30
def initialize ( url : , token : , page : DEFAULT_PAGE , per_page : DEFAULT_PER_PAGE , api_version : API_VERSION )
@url = url
2021-01-03 14:25:43 +05:30
@token = token & . strip
@page = page
@per_page = per_page
@api_version = api_version
2021-09-30 23:02:18 +05:30
@compatible_instance_version = false
2021-01-03 14:25:43 +05:30
end
def get ( resource , query = { } )
2021-09-04 01:27:46 +05:30
request ( :get , resource , query : query . reverse_merge ( request_query ) )
2021-01-29 00:20:46 +05:30
end
2021-06-08 01:23:25 +05:30
def post ( resource , body = { } )
2021-09-04 01:27:46 +05:30
request ( :post , resource , body : body )
end
def head ( resource )
request ( :head , resource )
end
def stream ( resource , & block )
request ( :get , resource , stream_body : true , & block )
2021-06-08 01:23:25 +05:30
end
2021-01-29 00:20:46 +05:30
def each_page ( method , resource , query = { } , & block )
return to_enum ( __method__ , method , resource , query ) unless block_given?
next_page = @page
2021-01-03 14:25:43 +05:30
2021-01-29 00:20:46 +05:30
while next_page
@page = next_page . to_i
response = self . public_send ( method , resource , query ) # rubocop: disable GitlabSecurity/PublicSend
collection = response . parsed_response
next_page = response . headers [ 'x-next-page' ] . presence
yield collection
end
2021-01-03 14:25:43 +05:30
end
2021-09-04 01:27:46 +05:30
def resource_url ( resource )
Gitlab :: Utils . append_path ( api_url , resource )
end
2021-11-18 22:05:49 +05:30
def instance_version
strong_memoize ( :instance_version ) do
response = with_error_handling do
Gitlab :: HTTP . get ( resource_url ( :version ) , default_options )
end
2021-09-30 23:02:18 +05:30
2021-11-18 22:05:49 +05:30
Gitlab :: VersionInfo . parse ( response . parsed_response [ 'version' ] )
2021-09-30 23:02:18 +05:30
end
2021-11-18 22:05:49 +05:30
end
def compatible_for_project_migration?
instance_version > = BulkImport . min_gl_version_for_project_migration
end
2021-09-30 23:02:18 +05:30
2021-11-18 22:05:49 +05:30
private
def validate_instance_version!
return if @compatible_instance_version
2021-09-30 23:02:18 +05:30
2021-11-18 22:05:49 +05:30
if instance_version . major < BulkImport :: MIN_MAJOR_VERSION
2021-09-30 23:02:18 +05:30
raise :: BulkImports :: Error . unsupported_gitlab_version
else
@compatible_instance_version = true
end
end
2021-09-04 01:27:46 +05:30
# rubocop:disable GitlabSecurity/PublicSend
def request ( method , resource , options = { } , & block )
2021-09-30 23:02:18 +05:30
validate_instance_version!
2021-09-04 01:27:46 +05:30
with_error_handling do
Gitlab :: HTTP . public_send (
method ,
resource_url ( resource ) ,
request_options ( options ) ,
& block
)
end
end
# rubocop:enable GitlabSecurity/PublicSend
def request_options ( options )
default_options . merge ( options )
end
def default_options
{
headers : request_headers ,
follow_redirects : false
}
end
2021-01-03 14:25:43 +05:30
def request_query
{
page : @page ,
per_page : @per_page
}
end
def request_headers
{
'Content-Type' = > 'application/json' ,
'Authorization' = > " Bearer #{ @token } "
}
end
def with_error_handling
response = yield
2022-01-26 12:08:38 +05:30
raise :: BulkImports :: NetworkError . new ( " Unsuccessful response #{ response . code } from #{ response . request . path . path } " , response : response ) unless response . success?
2021-01-03 14:25:43 +05:30
response
rescue * Gitlab :: HTTP :: HTTP_ERRORS = > e
2021-11-18 22:05:49 +05:30
raise :: BulkImports :: NetworkError , e
2021-01-03 14:25:43 +05:30
end
def api_url
2021-09-30 23:02:18 +05:30
Gitlab :: Utils . append_path ( @url , " /api/ #{ @api_version } " )
2021-01-03 14:25:43 +05:30
end
end
end
end