Hi,
This patch add support for reporting HTTP method in documentation for specific operation. Also table of parameters was redesigned a little bit and operation features was added.
-- Michal
--- server/lib/deltacloud/validation.rb | 38 ++++++++++-- server/lib/sinatra/rabbit.rb | 2 + server/public/stylesheets/compiled/application.css | 7 ++ server/server.rb | 10 ++-- server/views/docs/operation.html.haml | 66 +++++++++++++++----- 5 files changed, 95 insertions(+), 28 deletions(-)
diff --git a/server/lib/deltacloud/validation.rb b/server/lib/deltacloud/validation.rb index b4eb3ae..2ee040a 100644 --- a/server/lib/deltacloud/validation.rb +++ b/server/lib/deltacloud/validation.rb @@ -13,14 +13,30 @@ module Deltacloud::Validation end
class Param - attr_reader :name, :klass, :type, :options, :description + attr_reader :name, :klass, :type, :options, :validation, :description
def initialize(args) @name = args[0] @klass = args[1] || :string @type = args[2] || :optional - @options = args[3] || [] - @description = args[4] || '' + + case args[3].class.name + when 'Hash': + @validation = args[3][:format] + when 'Array': + @options = args[3] + when 'String': + @description = args[3] + end + + @description ||= args[4] || auto_docs(@name) || '' + end + + def auto_docs(name) + case name.to_sym + when :id + "The id of the object to retrieve." + end end
def required? @@ -61,9 +77,19 @@ module Deltacloud::Validation if p.required? and not values[p.name] raise Failure.new(p, "Required parameter #{p.name} not found") end - if values[p.name] and not p.options.empty? and - not p.options.include?(values[p.name]) - raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]} which is not in #{p.options.join(", ")}") + if values[p.name] and not p.options.empty? + if p.options.class == Hash + if p.options[:format] + p.validation = p.options[:format] + if values[p.name].match(Regexp.new(p.options[:format])).nil? + raise Failure.new(p, "Parameter #{p.name} has invalid format (#{p.options[:format].inspect})") + end + end + elsif p.options.class == Array + unless p.options.include?(values[p.name]) + raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]} which is not in #{p.options.join(',')}") + end + end end end end diff --git a/server/lib/sinatra/rabbit.rb b/server/lib/sinatra/rabbit.rb index 6018810..a7dfa0f 100644 --- a/server/lib/sinatra/rabbit.rb +++ b/server/lib/sinatra/rabbit.rb @@ -48,6 +48,8 @@ module Sinatra coll, oper = @collection, self ::Sinatra::Application.get("/api/docs/#{@collection.name}/#{@name}") do @collection, @operation = coll, oper + collection_features = driver.features(@collection.name) + @features = collection_features.select { |f| f.operations.collect{ |o| o.name }.include?(oper.name) } respond_to do |format| format.html { haml :'docs/operation' } format.xml { haml :'docs/operation' } diff --git a/server/public/stylesheets/compiled/application.css b/server/public/stylesheets/compiled/application.css index 969f712..a1f43c7 100644 --- a/server/public/stylesheets/compiled/application.css +++ b/server/public/stylesheets/compiled/application.css @@ -611,3 +611,10 @@ input[type='radio'] { table.docs { border : 1px solid #ccc } table.docs td { border : 1px solid #ccc } table.docs table td { border : none } + +p { margin : 1em 0; } +p.description { background : #eee; padding : 1em 0.5em; border : 1px dotted #ccc; } + +h2 { border-bottom : 1px solid #eee; } +code { font-family : monospace; font-weight : bold; } +td.type { color : red; font-weight : bold;} diff --git a/server/server.rb b/server/server.rb index b5bdfac..b262f81 100644 --- a/server/server.rb +++ b/server/server.rb @@ -226,9 +226,9 @@ collection :instances do
operation :create do description "Create a new instance" - param :image_id, :string, :required - param :realm_id, :string, :optional - param :hwp_id, :string, :optional + param :image_id, :string, :required, "The desired server image id" + param :realm_id, :string, :optional, "ID of realm you want to use for instance" + param :hwp_id, :string, :optional, "ID of hardware profile to use" control do @image = driver.image(credentials, :id => params[:image_id]) instance = driver.create_instance(credentials, @image.id, params) @@ -282,8 +282,8 @@ END
operation :index do description "List of available hardware profiles" - param :id, :string - param :architecture, :string, :optional, [ 'i386', 'x86_64' ] + param :id, :string, :optional + param :architecture, :string, :optional, [ 'i386', 'x86_64' ], "Show only profiles with given architecture" control do @profiles = driver.hardware_profiles(credentials, params) respond_to do |format| diff --git a/server/views/docs/operation.html.haml b/server/views/docs/operation.html.haml index ec6374b..8ec840a 100644 --- a/server/views/docs/operation.html.haml +++ b/server/views/docs/operation.html.haml @@ -1,31 +1,63 @@ +%h1 Documentation + %h2 - %a{:href => "/api/docs/#{@collection.name.to_s}"} #{@collection.name.to_s.titlecase} - #{'::'} - #{@operation.name} + ="#{@collection.name}/#{@operation.name}" +%p.description #{@operation.description} + +%h2 Request
-%p #{@operation.description} +%h3 URL +%p + ="#{url_for '/', :full}api/#{@collection.name}/#{@operation.name}"
-%br -%h3 - URL: - %u - = "/api/#{@collection.name.to_s}/#{@operation.name.to_s}" -%br -%h3 Parameters: +%h3 HTTP method
+%p + = @operation.method.to_s.upcase + +%h3 Input Request Query Parameters
%table %thead %tr + %th Required %th Name %th Type - %th Class - %th Valid values + %th Validation + %th{:style => 'width:25em'} Description %tbody - @operation.each_param do |p| %tr - %td{:style => "width:15em"} - %em #{p.name} - %td{:style => "width:10em"} #{p.type} + %td.type + =p.type if p.type.eql?(:required) + %td + %code #{p.name} %td #{p.klass} - %td{:style => "width:10em"} #{p.options.join(',')} + - if p.validation + %td #{p.validation.inspect if p.validation} + - elsif p.options + %td #{p.options.inspect} + - else + %td + %td #{p.description} + %tr + %td{:colspan => 5, :style => "background : #ccc"} + %strong Features: + - @features.each do |f| + - f.operations.collect { |o| [f, o.params ] }.each do |feature, feature_params| + %tr + %th{:colspan => 5} #{feature.name} + - feature_params.each do |name, p| + %tr + %td.type + =p.type if p.type.eql?(:required) + %td + %code #{name} + %td #{p.klass} + - if p.validation + %td #{p.validation.inspect if p.validation} + - elsif p.options + %td #{p.options.inspect} + - else + %td + %td #{p.description}
deltacloud-devel@lists.fedorahosted.org