[PATCH conductor] #3391 Represent the relationships between instances

Jan Provazník jprovazn at redhat.com
Fri Jul 13 18:22:32 UTC 2012


On 07/04/2012 06:03 PM, jzigmund at redhat.com wrote:
> From: Jozef Zigmund <jzigmund at redhat.com>
>
> ---
>   src/Gemfile.in                                     |    1 +
>   src/app/controllers/deployables_controller.rb      |   13 +++++++
>   src/app/models/deployable.rb                       |    1 +
>   src/app/util/deployable_xml.rb                     |   35 ++++++++++++++++++++
>   .../deployables/service_dependencies.html.haml     |   11 ++++++
>   src/app/views/deployables/show.html.haml           |    1 +
>   src/config/initializers/mime_types.rb              |    1 +
>   src/config/locales/en.yml                          |    1 +
>   src/config/routes.rb                               |    1 +
>   9 files changed, 65 insertions(+), 0 deletions(-)
>   create mode 100644 src/app/views/deployables/service_dependencies.html.haml
>
> diff --git a/src/Gemfile.in b/src/Gemfile.in
> index 1d90a91..7bb3704 100644
> --- a/src/Gemfile.in
> +++ b/src/Gemfile.in
> @@ -23,6 +23,7 @@ gem 'compass'
>   gem 'compass-960-plugin', :require=> 'ninesixty'
>   gem 'delayed_job', '~> 2.1.4'
>   gem 'paranoia'
> +gem 'graphviz'
>
>   platforms :ruby_18 do
>     gem 'fastercsv'
> diff --git a/src/app/controllers/deployables_controller.rb b/src/app/controllers/deployables_controller.rb
> index 3e3b76a..e4d3f91 100644
> --- a/src/app/controllers/deployables_controller.rb
> +++ b/src/app/controllers/deployables_controller.rb
> @@ -283,6 +283,19 @@ class DeployablesController < ApplicationController
>       redirect_to_original({"deployables_preset_filter" => params[:deployables_preset_filter], "deployables_search" => params[:deployables_search]})
>     end
>
> +  def service_dependencies
> +    deployable = Deployable.find(params[:id])
> +    deployable_xml = DeployableXML.new(deployable.xml)
> +    respond_to do |format|
> +      format.html do
> +        render :locals => {:deployable => deployable}
> +      end
> +      format.png do
> +        render :text => deployable_xml.display_digraph
> +      end
> +    end
> +  end
> +
>     private
>
>     def set_header
> diff --git a/src/app/models/deployable.rb b/src/app/models/deployable.rb
> index 9c6aff9..b052b44 100644
> --- a/src/app/models/deployable.rb
> +++ b/src/app/models/deployable.rb
> @@ -15,6 +15,7 @@
>   #
>
>   require 'util/conductor'
> +require 'util/deployable_xml'
>
>   class Deployable < ActiveRecord::Base
>     class << self
> diff --git a/src/app/util/deployable_xml.rb b/src/app/util/deployable_xml.rb
> index cdbbc39..ab46251 100644
> --- a/src/app/util/deployable_xml.rb
> +++ b/src/app/util/deployable_xml.rb
> @@ -17,6 +17,7 @@
>   =begin
>   XML Wrapper objects for the deployable XML format
>   =end
> +require "graphviz"
>
>   class ValidationError < RuntimeError; end
>
> @@ -100,6 +101,8 @@ end
>
>   class AssemblyXML
>
> +  attr_accessor :root
> +
>     def initialize(xmlstr_or_node = "")
>       if xmlstr_or_node.is_a? Nokogiri::XML::Node
>         @root = xmlstr_or_node
> @@ -202,6 +205,38 @@ class DeployableXML
>       @relax_file = "#{File.dirname(File.expand_path(__FILE__))}/deployable-rng.xml"
>     end
>
> +  def display_digraph
> +    graph = GraphViz.new(:G, :type => :digraph)
> +    if has_reference?
> +      draw_nodes(graph)
> +      draw_edges(graph)
> +    else
> +      draw_nodes(graph)
> +    end
> +    graph.output :png => String
> +  end
> +
> +  def draw_nodes(graph)
> +    assemblies.each do |assembly|
> +      graph.add_node(assembly.name)
> +    end
> +  end
> +
> +  def draw_edges(graph)
> +    assemblies.each do |assembly|
> +      references = assembly.root.xpath(".//reference")
> +      unless references.empty?
> +        references.each do |reference|
> +          graph.add_edge(assembly.name, reference.attributes['assembly'].value)
> +        end
> +      end
> +    end
> +  end
> +
> +  def has_reference?
> +     not @root.xpath("//reference").empty?
> +  end
> +
>     def name
>       @root["name"] if @root
>     end
> diff --git a/src/app/views/deployables/service_dependencies.html.haml b/src/app/views/deployables/service_dependencies.html.haml
> new file mode 100644
> index 0000000..075de04
> --- /dev/null
> +++ b/src/app/views/deployables/service_dependencies.html.haml
> @@ -0,0 +1,11 @@
> += render :partial => 'layouts/admin_nav'
> +%header.page-header
> +  .obj_actions
> +    .button-group
> +      - if check_privilege(Privilege::MODIFY, deployable)
> +        = link_to t('deployables.show.edit'), edit_polymorphic_path([@catalog, deployable]), :class => 'button', :id => 'edit_button'
> +        = link_to t('deployables.show.edit_xml'), edit_polymorphic_path([@catalog, deployable], :edit_xml => true), :class => 'button', :id => 'edit_xml_button'
> +        = button_to t('delete'), polymorphic_path([@catalog, deployable]), :method => 'delete', :confirm => "#{t'catalog_entries.show.confirm_delete'}", :class => 'button danger', :id => 'delete'
> +  %h1.catalog_entries= deployable.name
> +%p
> +  = image_tag(service_dependencies_deployable_path(deployable, :format => :png))
> \ No newline at end of file
> diff --git a/src/app/views/deployables/show.html.haml b/src/app/views/deployables/show.html.haml
> index a7ee021..d28db60 100644
> --- a/src/app/views/deployables/show.html.haml
> +++ b/src/app/views/deployables/show.html.haml
> @@ -3,6 +3,7 @@
>     .obj_actions
>       .button-group
>         - if check_privilege(Privilege::MODIFY, @deployable)
> +        = link_to t(".dependencies_diagram"), service_dependencies_deployable_path(@deployable, :catalog_id => @catalog, :pushed_count => @pushed_count), :class => 'button'
>           = link_to t('.edit'), edit_polymorphic_path([@catalog, @deployable]), :class => 'button', :id => 'edit_button'
>           = link_to t('.edit_xml'), edit_polymorphic_path([@catalog, @deployable], :edit_xml => true), :class => 'button', :id => 'edit_xml_button'
>           = button_to t('.delete'), polymorphic_path([@catalog, @deployable]), :method => 'delete', :confirm => "#{t'catalog_entries.show.confirm_delete'}", :class => 'button danger', :id => 'delete'
> diff --git a/src/config/initializers/mime_types.rb b/src/config/initializers/mime_types.rb
> index 18ecf33..bd77cce 100644
> --- a/src/config/initializers/mime_types.rb
> +++ b/src/config/initializers/mime_types.rb
> @@ -20,3 +20,4 @@
>   # Mime::Type.register "text/richtext", :rtf
>   # Mime::Type.register_alias "text/html", :iphone
>   Mime::Type.register "image/svg+xml", :svg
> +Mime::Type.register "image/png", :png
> diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
> index 9295373..1684721 100644
> --- a/src/config/locales/en.yml
> +++ b/src/config/locales/en.yml
> @@ -1036,6 +1036,7 @@ en:
>         n_a: "N/A"
>         uuids: "UUIDs"
>         show_hide_uuids: "Show/Hide"
> +      dependencies_diagram: Dependencies Diagram
>       form:
>         choose_xml: Choose Deployable XML file
>         catalog: Catalog
> diff --git a/src/config/routes.rb b/src/config/routes.rb
> index e7f26c5..18ed7f2 100644
> --- a/src/config/routes.rb
> +++ b/src/config/routes.rb
> @@ -237,6 +237,7 @@ Conductor::Application.routes.draw do
>       end
>       member do
>         get :definition
> +      get :service_dependencies
>       end
>     end
>
>

Hi Jozef,
I didn't have time to do a proper review yet, but have a few findings 
about this so far:
- graphviz has many pkg dependencies (it added 41 new pkgs). Maybe it 
could be optional - if graphviz is not installed, one some warning about 
missing graphviz would be displayed.
- there is also already packaged graphviz-ruby gem - couldn't this be 
used? I didn't check this, maybe it's not sufficient, but it could save 
us some packaging
- it seems that this code generates dependencies between assemblies, 
what we need are dependencies between services: so nodes would be 
services, edges would represent param references, assembly would be 
represented by a frame around services belonging to this assembly.

I checked deployable xml schema and what confuses me is that it seems 
that a service param can reference a service _or_ an assembly (according 
to param definition in app/util/deployable-rng.xml). If a param 
references assembly, then we can't resolve dependencies between 
services. Dan, you are most familiar with this - what do you think about 
it? As I understand it, referencing whole assemblies should be disabled.

Jan



More information about the aeolus-devel mailing list