Merge branch '11917-dont-clear-cache'
[arvados.git] / apps / workbench / app / helpers / provenance_helper.rb
index 44acc18a019759342f94c15c3e1bafd9207be758..94092a12ea10c1875067624778aa4c56ee7f6441 100644 (file)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 module ProvenanceHelper
 
   class GenerateGraph
@@ -37,9 +41,15 @@ module ProvenanceHelper
           return "\"#{uuid}\" [label=\"(empty collection)\"];\n"
         end
 
-        href = url_for ({:controller => Collection.to_s.tableize,
-                          :action => :show,
-                          :id => uuid.to_s })
+        if describe_opts[:col_uuid]
+          href = url_for ({:controller => Collection.to_s.tableize,
+                           :action => :show,
+                           :id => describe_opts[:col_uuid].to_s })
+        else
+          href = url_for ({:controller => Collection.to_s.tableize,
+                           :action => :show,
+                           :id => uuid.to_s })
+        end
 
         return "\"#{uuid}\" [label=\"#{encode_quotes(describe_opts[:label] || (@pdata[uuid] and @pdata[uuid][:name]) || uuid)}\",shape=box,href=\"#{href}\",#{bgcolor}];\n"
       else
@@ -104,37 +114,6 @@ module ProvenanceHelper
       gr
     end
 
-    def cr_edges cr
-      uuid = cr[:uuid]
-      gr = ""
-
-      # Search for input mounts
-      input_obj = cr[:mounts].andand[:"/var/lib/cwl/cwl.input.json"].andand[:content] || cr[:mounts] || {}
-      if input_obj
-        ProvenanceHelper::find_collections input_obj, 'input' do |col_hash, col_uuid, key|
-          if col_uuid
-            gr += describe_node(col_uuid)
-            gr += edge(col_uuid, uuid, {:label => key})
-          else
-            gr += describe_node(col_hash)
-            gr += edge(col_hash, uuid, {:label => key})
-          end
-        end
-      end
-
-      [
-        [:output_uuid, 'output'],
-        [:log_uuid, 'log']
-      ].each do |attr, label|
-        if cr[attr]
-          gr += describe_node(cr[attr])
-          gr += edge(uuid, cr[attr], {label: label})
-        end
-      end
-
-      gr
-    end
-
     def job_edges job, edge_opts={}
       uuid = job_uuid(job)
       gr = ""
@@ -218,18 +197,49 @@ module ProvenanceHelper
         elsif rsc == ContainerRequest
           cr = @pdata[uuid]
           if cr
-            gr += cr_edges cr
-            gr += describe_node(uuid, {href: {controller: 'container_requests',
-                                              id: uuid},
-                                       label: @pdata[uuid][:name],
-                                       shape: 'oval'})
-            # Search for child CRs
-            if cr[:container_uuid]
-              child_crs = ContainerRequest.where(requesting_container_uuid: cr[:container_uuid])
-              child_crs.each do |child|
-                gr += generate_provenance_edges(child[:uuid])
-                gr += edge(uuid, child[:uuid], {label: 'child'})
+            gr += describe_node(cr[:uuid], {href: {controller: 'container_requests',
+                                                   id: cr[:uuid]},
+                                            label: cr[:name],
+                                            shape: 'oval'})
+            # Connect child CRs
+            children = @opts[:cr_children_of].andand[cr[:uuid]]
+            if children
+              children.each do |child|
+                gr += edge(child[:uuid], cr[:uuid], {label: 'child'})
+              end
+            end
+            # Output collection node
+            if cr[:output_uuid] and @opts[:output_collections][cr[:output_uuid]]
+              c = @opts[:output_collections][cr[:output_uuid]]
+              gr += describe_node(c[:portable_data_hash],
+                                  {
+                                    label: c[:name],
+                                    col_uuid: c[:uuid],
+                                  })
+              gr += edge(cr[:uuid],
+                         c[:portable_data_hash],
+                         {label: 'output'})
+            end
+            # Input collection nodes
+            output_pdhs = @opts[:output_collections].values.collect{|c|
+              c[:portable_data_hash]}
+            ProvenanceHelper::cr_input_pdhs(cr).each do |pdh|
+              if not output_pdhs.include?(pdh)
+                # Search for collections on the same project first
+                cols = @opts[:input_collections][pdh].andand.select{|c|
+                  c[:owner_uuid] == cr[:owner_uuid]}
+                if not cols or cols.empty?
+                  # Search for any collection with this PDH
+                  cols = @opts[:input_collections][pdh]
+                end
+                names = cols.collect{|x| x[:name]}.uniq
+                input_name = names.first
+                if names.length > 1
+                  input_name += " + #{names.length - 1} more"
+                end
+                gr += describe_node(pdh, {label: input_name})
               end
+              gr += edge(pdh, cr[:uuid], {label: 'input'})
             end
           end
         end
@@ -377,4 +387,17 @@ edge [fontsize=10,fontname=\"Helvetica,Arial,sans-serif\"];
       end
     end
   end
+
+  def self.cr_input_pdhs cr
+    pdhs = []
+    input_obj = cr[:mounts].andand[:"/var/lib/cwl/cwl.input.json"].andand[:content] || cr[:mounts]
+    if input_obj
+      find_collections input_obj do |col_hash, col_uuid, key|
+        if col_hash
+          pdhs << col_hash
+        end
+      end
+    end
+    pdhs
+  end
 end