require 'httpclient'
require 'nokogiri'
require 'yaml'
module NexusCli
class ProRemote < OSSRemote
# Gets the custom metadata for an artifact
# @param [String] artifact The GAVE string of the artifact
# @result [String] The resulting custom metadata xml from the get operation
def get_artifact_custom_info_raw(artifact)
group_id, artifact_id, version, extension = parse_artifact_string(artifact)
encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
response = nexus.get(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"))
case response.status
when 200
if N3Metadata::missing_custom_metadata?(response.content)
raise N3NotFoundException
else
return response.content
end
when 404
raise ArtifactNotFoundException
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
# Gets the custom metadata for an artifact in a simplified XML format
# @param [String] artifact The GAVE string of the artifact
# @result [String] The resulting custom metadata xml from the get operation
def get_artifact_custom_info(artifact)
N3Metadata::convert_result_to_simple_xml(get_artifact_custom_info_raw(artifact))
end
# Updates custom metadata for an artifact
# @param [String] artifact The GAVE string of the artifact
# @param [Array] *params The array of key:value strings
# @result [Integer] The resulting exit code of the operation
def update_artifact_custom_info(artifact, *params)
target_n3 = parse_custom_metadata_update_params(*params)
# Get all the urn:nexus/user# keys and consolidate.
# Read in nexus n3 file. If this is a newly-added artifact, there will be no n3 file so escape the exception.
begin
nexus_n3 = N3Metadata::convert_result_to_hash(get_artifact_custom_info_raw(artifact))
rescue N3NotFoundException
nexus_n3 = {}
end
group_id, artifact_id, version, extension = parse_artifact_string(artifact)
encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
response = nexus.post(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"), :body => create_custom_metadata_update_json(nexus_n3, target_n3), :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.code
when 201
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
# Clears all custom metadata from an artifact
# @param [String] The GAVE string of the artifact
# @result [Integer] The resulting exit code of the operation
def clear_artifact_custom_info(artifact)
get_artifact_custom_info(artifact) # Check that artifact has custom metadata
group_id, artifact_id, version, extension = parse_artifact_string(artifact)
encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
response = nexus.post(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"), :body => create_custom_metadata_clear_json, :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.status
when 201
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
# Searches for artifacts using custom metadata
# @param [Array] *params The array of key:type:value strings
# @result [String] The resulting xml from the search
def search_artifacts_custom(*params)
nodesets = Array.new
parse_custom_metadata_search_params(*params).each do |param|
response = nexus.get(nexus_url("service/local/search/m2/freeform"), :query => {:p => param[0], :t => param[1], :v => param[2]})
case response.status
when 200
nodesets.push(Nokogiri::XML(response.body).xpath("/search-results/data"))
when 400
raise BadSearchRequestException
when 404
raise ArtifactNotFoundException
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
# Perform array intersection across all NodeSets for the final common set.
result = nodesets.inject(nodesets.first) {|memo, nodeset| get_common_artifact_set(memo, nodeset)}
return result.nil? ? "" : result.to_xml(:indent => 4)
end
def get_pub_sub(repository_id)
response = nexus.get(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"))
case response.status
when 200
return response.content
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def enable_artifact_publish(repository_id)
params = {:repositoryId => repository_id}
params[:publish] = true
artifact_publish(repository_id, params)
end
def disable_artifact_publish(repository_id)
params = {:repositoryId => repository_id}
params[:publish] = false
artifact_publish(repository_id, params)
end
def artifact_publish(repository_id, params)
response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.status
when 200
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def enable_artifact_subscribe(repository_id)
raise NotProxyRepositoryException.new(repository_id) unless Nokogiri::XML(get_repository_info(repository_id)).xpath("/repository/data/repoType").first.content == "proxy"
params = {:repositoryId => repository_id}
params[:subscribe] = true
artifact_subscribe(repository_id, params)
end
def disable_artifact_subscribe(repository_id)
raise NotProxyRepositoryException.new(repository_id) unless Nokogiri::XML(get_repository_info(repository_id)).xpath("/repository/data/repoType").first.content == "proxy"
params = {:repositoryId => repository_id}
params[:subscribe] = false
artifact_subscribe(repository_id, params)
end
def artifact_subscribe(repository_id, params)
response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.status
when 200
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def enable_smart_proxy(host=nil, port=nil)
params = {:enabled => true}
params[:host] = host unless host.nil?
params[:port] = port unless port.nil?
smart_proxy(params)
end
def disable_smart_proxy
params = {:enabled => false}
smart_proxy(params)
end
def smart_proxy(params)
response = nexus.put(nexus_url("service/local/smartproxy/settings"), :body => create_smart_proxy_settings_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.status
when 200
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def get_smart_proxy_settings
response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
case response.status
when 200
return response.content
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def get_smart_proxy_key
response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
case response.status
when 200
return response.content
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def add_trusted_key(certificate, description, path=true)
params = {:description => description}
params[:certificate] = path ? File.read(File.expand_path(certificate)) : certificate
response = nexus.post(nexus_url("service/local/smartproxy/trusted-keys"), :body => create_add_trusted_key_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
case response.status
when 201
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def delete_trusted_key(key_id)
response = nexus.delete(nexus_url("service/local/smartproxy/trusted-keys/#{key_id}"))
case response.status
when 204
return true
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def get_trusted_keys
response = nexus.get(nexus_url("service/local/smartproxy/trusted-keys"), :header => DEFAULT_ACCEPT_HEADER)
case response.status
when 200
return response.content
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def get_license_info
response = nexus.get(nexus_url("service/local/licensing"), :header => DEFAULT_ACCEPT_HEADER)
case response.status
when 200
return response.content
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def install_license(license_file)
file = File.read(File.expand_path(license_file))
response = nexus.post(nexus_url("service/local/licensing/upload"), :body => file, :header => {"Content-Type" => "application/octet-stream"})
case response.status
when 201
return true
when 403
raise LicenseInstallFailure
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
def install_license_bytes(bytes)
response = nexus.post(nexus_url("service/local/licensing/upload"), :body => bytes, :header => {"Content-Type" => "application/octet-stream"})
case response.status
when 201
return true
when 403
raise LicenseInstallFailure
else
raise UnexpectedStatusCodeException.new(response.status)
end
end
private
def create_add_trusted_key_json(params)
JSON.dump(:data => params)
end
def create_smart_proxy_settings_json(params)
JSON.dump(:data => params)
end
def create_pub_sub_json(params)
JSON.dump(:data => params)
end
# Converts an array of parameters used to update custom metadata
# @param [Array] *params The array of key:value strings
# @return [Hash] The resulting hash of parsed key:value items
# @example
# parse_custom_metadata_update_params(["cookie:oatmeal raisin"]) #=> {"cookie"=>"oatmeal raisin"}
def parse_custom_metadata_update_params(*params)
params.inject({}) do |parsed_params, param|
# param = key:value
metadata_key, metadata_value = param.split(":", 2)
if N3Metadata::valid_n3_key?(metadata_key) && N3Metadata::valid_n3_value?(metadata_value)
parsed_params[metadata_key] = metadata_value
else
raise N3ParameterMalformedException
end
parsed_params
end
end
# Converts an array of parameters used to search by custom metadata
# @param [Array] *params The array of key:type:value strings
# @result [Array] The resulting array of parsed key:type:value items
# @example
# parse_custom_metadata_search_params(["cookie:matches:oatmeal raisin"]) #=> #=> [["cookie","matches","oatmeal raisin"]]
def parse_custom_metadata_search_params(*params)
params.inject([]) do |parsed_params, param|
# param = key:type:value
metadata_key, search_type, metadata_value = param.split(":", 3)
if N3Metadata::valid_n3_key?(metadata_key) && N3Metadata::valid_n3_value?(metadata_value) && N3Metadata::valid_n3_search_type?(search_type)
parsed_params.push([metadata_key, search_type, metadata_value])
else
raise SearchParameterMalformedException
end
parsed_params
end
end
def create_custom_metadata_update_json(source, target)
JSON.dump(:data => N3Metadata::create_metadata_hash(source, target))
end
def create_custom_metadata_clear_json
JSON.dump(:data => {})
end
# Gets the intersection of two artifact arrays, returning the common set
# @param [Array] set1, set2 The two Nokogiri::NodeSet objects to intersect
# @result [Nokogiri::NodeSet] The resulting object generated from the array intersect
def get_common_artifact_set(set1, set2)
intersection = get_artifact_array(set1) & get_artifact_array(set2)
return intersection.count > 0 ? Nokogiri::XML("#{intersection.join}").root : Nokogiri::XML("").root
end
# Collect elements into an array
# @info This will allow use of array intersection to find common artifacts in searches
# @param [Nokogiri::NodeSet] set The object to be divided by elements
# @result [Array] The result array of artifact elements
def get_artifact_array(set)
set.search("//artifact").inject([]) do |artifacts, artifact|
artifacts.push(artifact.to_s)
artifacts
end
end
end
end