super
end
- def script_param_edges(visited, sp)
+ def find_collections(visited, sp, &b)
case sp
+ when ArvadosModel
+ sp.class.columns.each do |c|
+ find_collections(visited, sp[c.name.to_sym], &b) if c.name != "log"
+ end
when Hash
sp.each do |k, v|
- script_param_edges(visited, v)
+ find_collections(visited, v, &b)
end
when Array
sp.each do |v|
- script_param_edges(visited, v)
+ find_collections(visited, v, &b)
end
when String
- return if sp.empty?
- if loc = Keep::Locator.parse(sp)
- search_edges(visited, loc.to_s, :search_up)
+ if m = /[a-f0-9]{32}\+\d+/.match(sp)
+ yield m[0], nil
+ elsif m = /[0-9a-z]{5}-4zz18-[0-9a-z]{15}/.match(sp)
+ yield nil, m[0]
end
end
end
if loc
# uuid is a portable_data_hash
- c = Collection.readable_by(*@read_users).where(portable_data_hash: loc.to_s).all
+ collections = Collection.readable_by(*@read_users).where(portable_data_hash: loc.to_s)
+ c = collections.limit(2).all
if c.size == 1
- visited[loc.to_s] = c
+ visited[loc.to_s] = c[0]
elsif c.size > 1
- visited[loc.to_s] = {
- portable_data_hash: c[0].portable_data_hash,
- name: "#{c[0].name} + #{c.size-1} more"
- }
+ name = collections.limit(1).where("name <> ''").first
+ if name
+ visited[loc.to_s] = {
+ portable_data_hash: c[0].portable_data_hash,
+ name: "#{name.name} + #{collections.count-1} more"
+ }
+ else
+ visited[loc.to_s] = {
+ portable_data_hash: c[0].portable_data_hash,
+ name: loc.to_s
+ }
+ end
end
if direction == :search_up
Job.readable_by(*@read_users).where(["jobs.script_parameters like ?", "%#{loc.to_s}%"]).each do |job|
search_edges(visited, job.uuid, :search_down)
end
+
+ Job.readable_by(*@read_users).where(["jobs.docker_image_locator = ?", "#{loc.to_s}"]).each do |job|
+ search_edges(visited, job.uuid, :search_down)
+ end
end
else
# uuid is a regular Arvados UUID
visited[uuid] = job.as_api_response
if direction == :search_up
# Follow upstream collections referenced in the script parameters
- script_param_edges(visited, job.script_parameters)
+ find_collections(visited, job) do |hash, uuid|
+ search_edges(visited, hash, :search_up) if hash
+ search_edges(visited, uuid, :search_up) if uuid
+ end
elsif direction == :search_down
# Follow downstream job output
search_edges(visited, job.output, direction)
def provenance
visited = {}
- search_edges(visited, @object[:uuid] || @object[:portable_data_hash], :search_up)
+ search_edges(visited, @object[:portable_data_hash], :search_up)
+ search_edges(visited, @object[:uuid], :search_up)
render json: visited
end
def used_by
visited = {}
- search_edges(visited, @object[:uuid] || @object[:portable_data_hash], :search_down)
+ search_edges(visited, @object[:uuid], :search_down)
+ search_edges(visited, @object[:portable_data_hash], :search_down)
render json: visited
end