2020-10-05 11:08:56 -04:00
# frozen_string_literal: true
2020-10-23 11:08:42 -04:00
module BulkImports
module Clients
2021-06-11 11:09:58 -04:00
class HTTP
2021-10-13 08:12:20 -04:00
include Gitlab :: Utils :: StrongMemoize
2021-03-23 08:09:33 -04:00
API_VERSION = 'v4'
2021-03-25 23:09:21 -04:00
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 30
2020-10-05 11:08:56 -04:00
2021-07-08 08:08:30 -04:00
def initialize ( url : , token : , page : DEFAULT_PAGE , per_page : DEFAULT_PER_PAGE , api_version : API_VERSION )
@url = url
2020-10-05 11:08:56 -04:00
@token = token & . strip
@page = page
@per_page = per_page
@api_version = api_version
2021-06-25 08:07:44 -04:00
@compatible_instance_version = false
2020-10-05 11:08:56 -04:00
end
def get ( resource , query = { } )
2021-05-20 14:10:33 -04:00
request ( :get , resource , query : query . reverse_merge ( request_query ) )
2020-11-06 04:08:56 -05:00
end
2021-05-11 11:10:20 -04:00
def post ( resource , body = { } )
2021-05-20 14:10:33 -04:00
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-05-11 11:10:20 -04:00
end
2020-11-06 04:08:56 -05:00
def each_page ( method , resource , query = { } , & block )
return to_enum ( __method__ , method , resource , query ) unless block_given?
next_page = @page
2020-10-05 11:08:56 -04:00
2020-11-06 04:08:56 -05:00
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
2020-10-05 11:08:56 -04:00
end
2021-05-20 14:10:33 -04:00
def resource_url ( resource )
Gitlab :: Utils . append_path ( api_url , resource )
end
2021-10-13 08:12:20 -04:00
def instance_version
strong_memoize ( :instance_version ) do
response = with_error_handling do
Gitlab :: HTTP . get ( resource_url ( :version ) , default_options )
end
2021-06-25 08:07:44 -04:00
2021-10-13 08:12:20 -04:00
Gitlab :: VersionInfo . parse ( response . parsed_response [ 'version' ] )
2021-06-25 08:07:44 -04:00
end
2021-10-13 08:12:20 -04:00
end
def compatible_for_project_migration?
instance_version > = BulkImport . min_gl_version_for_project_migration
end
2021-06-25 08:07:44 -04:00
2021-10-13 08:12:20 -04:00
private
def validate_instance_version!
return if @compatible_instance_version
2021-06-25 08:07:44 -04:00
2021-10-13 08:12:20 -04:00
if instance_version . major < BulkImport :: MIN_MAJOR_VERSION
2021-06-25 08:07:44 -04:00
raise :: BulkImports :: Error . unsupported_gitlab_version
else
@compatible_instance_version = true
end
end
2021-05-20 14:10:33 -04:00
# rubocop:disable GitlabSecurity/PublicSend
def request ( method , resource , options = { } , & block )
2021-06-25 08:07:44 -04:00
validate_instance_version!
2021-05-20 14:10:33 -04:00
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
2020-10-05 11:08:56 -04:00
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
2021-12-01 04:10:25 -05:00
raise :: BulkImports :: NetworkError . new ( " Unsuccessful response #{ response . code } from #{ response . request . path . path } " , response : response ) unless response . success?
2020-10-05 11:08:56 -04:00
response
rescue * Gitlab :: HTTP :: HTTP_ERRORS = > e
2021-09-30 02:09:27 -04:00
raise :: BulkImports :: NetworkError , e
2020-10-05 11:08:56 -04:00
end
def api_url
2021-07-08 08:08:30 -04:00
Gitlab :: Utils . append_path ( @url , " /api/ #{ @api_version } " )
2020-10-05 11:08:56 -04:00
end
end
end
end