# frozen_string_literal: truerequire'net/http'require'uri'require'rexml/document'require'openssl'moduleKPMmoduleNexusFacadeclassUnexpectedStatusCodeException<StandardErrordefinitialize(code)@code=codeenddefmessage"The server responded with a #{@code} status code which is unexpected."endendclassArtifactMalformedException<StandardErrorclass<<selfdefmessage'Please submit your request using 4 colon-separated values. `groupId:artifactId:version:extension`'endendend# This is an extract and slim down of functions needed from nexus_cli to maintain the response expected by the base_artifact.classNexusApiCallsV2READ_TIMEOUT_DEFAULT=60OPEN_TIMEOUT_DEFAULT=60ERROR_MESSAGE_404='The artifact you requested information for could not be found. Please ensure it exists inside the Nexus.'attr_reader:version,:configuration,:ssl_verifyattr_accessor:loggerdefinitialize(configuration,ssl_verify,logger)@configuration=configuration@ssl_verify=ssl_verify@logger=loggerenddefsearch_for_artifacts(coordinates)logger.debug"Entered - Search for artifact, coordinates: #{coordinates}"response=get_response(coordinates,search_for_artifact_endpoint(coordinates),%i[g a])caseresponse.codewhen'200'logger.debug"response body: #{response.body}"response.bodywhen'404'raiseStandardError,ERROR_MESSAGE_404elseraiseUnexpectedStatusCodeException,response.codeendenddefget_artifact_info(coordinates)get_response_with_retries(coordinates,get_artifact_info_endpoint(coordinates),nil)enddefpull_artifact(coordinates,destination)file_name=get_file_name(coordinates)destination=File.join(File.expand_path(destination||'.'),file_name)logger.debug{"Downloading to destination: #{destination}"}File.open(destination,'wb')do|io|io.write(get_response_with_retries(coordinates,pull_artifact_endpoint(coordinates),nil))end{file_name: file_name,file_path: File.expand_path(destination),version: version,size: File.size(File.expand_path(destination))}enddefpull_artifact_endpoint(_coordinates)'/service/local/artifact/maven/redirect'enddefget_artifact_info_endpoint(_coordinates)'/service/local/artifact/maven/resolve'enddefsearch_for_artifact_endpoint(_coordinates)'/service/local/lucene/search'enddefbuild_query_params(coordinates,what_parameters=nil)artifact=parse_coordinates(coordinates)@version=artifact[:version].to_squery={g: artifact[:group_id],a: artifact[:artifact_id],e: artifact[:extension],v: version,r: configuration[:repository]}query.merge!(c: artifact[:classifier])unlessartifact[:classifier].nil?params=what_parameters.nil??query:{}what_parameters.each{|key|params[key]=query[key]unlessquery[key].nil?}unlesswhat_parameters.nil?params.map{|key,value|"#{key}=#{value}"}.join('&')endprivatedefparse_coordinates(coordinates)raiseArtifactMalformedExceptionifcoordinates.nil?split_coordinates=coordinates.split(':')raiseArtifactMalformedExceptionifsplit_coordinates.empty?||(split_coordinates.size>5)artifact={}artifact[:group_id]=split_coordinates[0]artifact[:artifact_id]=split_coordinates[1]artifact[:extension]=split_coordinates.size>3?split_coordinates[2]:'jar'artifact[:classifier]=split_coordinates.size>4?split_coordinates[3]:nilartifact[:version]=split_coordinates[-1]artifact[:version].upcase!ifversion=='latest'artifactenddefget_file_name(coordinates)artifact=parse_coordinates(coordinates)artifact[:version]=REXML::Document.new(get_artifact_info(coordinates)).elements['//version'].textifartifact[:version].casecmp('latest')ifartifact[:classifier].nil?"#{artifact[:artifact_id]}-#{artifact[:version]}.#{artifact[:extension]}"else"#{artifact[:artifact_id]}-#{artifact[:version]}-#{artifact[:classifier]}.#{artifact[:extension]}"endenddefget_response_with_retries(coordinates,endpoint,what_parameters)logger.debug{"Fetching coordinates=#{coordinates}, endpoint=#{endpoint}, params=#{what_parameters}"}response=get_response(coordinates,endpoint,what_parameters)logger.debug{"Response body: #{response.body}"}process_response_with_retries(response)enddefprocess_response_with_retries(response)caseresponse.codewhen'200'response.bodywhen'301','302','307'location=response['Location']logger.debug{"Following redirect to #{location}"}new_path=location.gsub!(configuration[:url],'')ifnew_path.nil?# Redirect to another domain (e.g. CDN)get_raw_response_with_retries(location)elseget_response_with_retries(nil,location,nil)endwhen'404'raiseStandardError,ERROR_MESSAGE_404elseraiseUnexpectedStatusCodeException,response.codeendenddefget_response(coordinates,endpoint,what_parameters)http=build_httpquery_params=build_query_params(coordinates,what_parameters)unlesscoordinates.nil?endpoint=endpoint_with_params(endpoint,query_params)unlesscoordinates.nil?request=Net::HTTP::Get.new(endpoint)ifconfiguration.key?(:username)&&configuration.key?(:password)request.basic_auth(configuration[:username],configuration[:password])elsifconfiguration.key?(:token)request['Authorization']="token #{configuration[:token]}"endlogger.debugdohttp.set_debug_output(logger)"HTTP path: #{endpoint}"endhttp.request(request)enddefbuild_httpuri=URI.parse(configuration[:url])http=Net::HTTP.new(uri.host,uri.port)http.open_timeout=configuration[:open_timeout]||OPEN_TIMEOUT_DEFAULT# secondshttp.read_timeout=configuration[:read_timeout]||READ_TIMEOUT_DEFAULT# secondshttp.use_ssl=(ssl_verify!=false)http.verify_mode=OpenSSL::SSL::VERIFY_NONEunlessssl_verifylogger.debug{"HTTP connection: #{http.inspect}"}httpenddefget_raw_response_with_retries(location)response=Net::HTTP.get_response(URI(location))logger.debug{"Response body: #{response.body}"}process_response_with_retries(response)enddefendpoint_with_params(endpoint,query_params)"#{endpoint}?#{URI::DEFAULT_PARSER.escape(query_params)}"endendendend