From: Michal Fojtik <[email protected]> * The 'entity_url' helpers are now generated from the Rabbit collections directory, instead of guessing them using method_missing.
* rake cimi:routes added to list all CIMI routes * rake routes now print URL helper instead of description Signed-off-by: Michal fojtik <[email protected]> --- server/Rakefile | 52 ++++++----- server/lib/cimi/collections/base.rb | 2 +- server/lib/cimi/helpers.rb | 1 - server/lib/cimi/models/cloud_entry_point.rb | 2 +- server/lib/cimi/server.rb | 2 + server/lib/deltacloud/collections.rb | 4 +- server/lib/deltacloud/collections/base.rb | 3 +- server/lib/deltacloud/core_ext/hash.rb | 8 ++ server/lib/deltacloud/core_ext/string.rb | 5 ++ server/lib/deltacloud/helpers.rb | 1 - server/lib/deltacloud/helpers/rabbit_helper.rb | 47 ++++++++++ server/lib/deltacloud/helpers/url_helper.rb | 115 ------------------------- server/lib/deltacloud/server.rb | 2 + 13 files changed, 102 insertions(+), 142 deletions(-) delete mode 100644 server/lib/deltacloud/helpers/url_helper.rb diff --git a/server/Rakefile b/server/Rakefile index 80d45d3..34c126e 100644 --- a/server/Rakefile +++ b/server/Rakefile @@ -86,36 +86,48 @@ namespace :mock do end desc "List the routes defined by Rabbit" -task :routes do - load File.join(File.dirname(__FILE__), 'config.ru') - Deltacloud.collections.each do |c| - puts "\033[1;32;m#{c.name}\33[0m" - c.operations.each do |o| - puts "\033[1;37m%6s\033[0m :%-10s %-30s (%s)" % [ - o.http_method.to_s.upcase, - o.operation_name, - o.full_path, - o.description[0..100] - ] - end - unless c.collections.empty? - puts - c.collections.each do |s| - puts "\033[1;32;m#{s.name}\33[0m" - s.operations.each do |o| - puts "\033[1;37m%6s\033[0m :%-10s %-30s (%s)" % [ +[:cimi, :deltacloud].each do |frontend| + namespace frontend do + desc "Print all routes defined for #{frontend.to_s.capitalize}" + task :routes do + ENV['API_FRONTEND'] = frontend.to_s + load File.join(File.dirname(__FILE__), 'config.ru') + f_class = (frontend == :cimi) ? CIMI : Deltacloud + f_class.collections.each do |c| + puts "\033[1;32;m#{c.name}\33[0m" + c.operations.each do |o| + puts "\033[1;37m%6s\033[0m :%-10s %-35s (%s)" % [ o.http_method.to_s.upcase, o.operation_name, o.full_path, - o.description[0..100] + Sinatra::Rabbit.generate_url_helper_for(c, o)[1] ] end + unless c.collections.empty? + puts + c.collections.each do |s| + puts "\033[1;32;m#{s.name}\33[0m" + s.operations.each do |o| + puts "\033[1;37m%6s\033[0m :%-10s %-35s (%s)" % [ + o.http_method.to_s.upcase, + o.operation_name, + o.full_path, + o.description[0..100] + ] + end + end + end + puts end end - puts end end +desc 'List Deltacloud routes' +task :routes do + Rake::Task['deltacloud:routes'].invoke +end + DRIVERS = [:mock, :ec2, :rhevm, :google, :gogrid, :openstack] desc 'Run all tests' diff --git a/server/lib/cimi/collections/base.rb b/server/lib/cimi/collections/base.rb index 7adb58d..00620fb 100644 --- a/server/lib/cimi/collections/base.rb +++ b/server/lib/cimi/collections/base.rb @@ -24,7 +24,7 @@ module CIMI::Collections helpers Deltacloud::Helpers::Drivers helpers Sinatra::AuthHelper - helpers Sinatra::UrlForHelper + helpers Sinatra::Rabbit::URLHelper helpers Deltacloud::Helpers::Application helpers CIMI::Helper diff --git a/server/lib/cimi/helpers.rb b/server/lib/cimi/helpers.rb index 6513ed9..9d069b1 100644 --- a/server/lib/cimi/helpers.rb +++ b/server/lib/cimi/helpers.rb @@ -30,7 +30,6 @@ require_relative '../deltacloud/drivers' require_relative '../deltacloud/models' require_relative '../deltacloud/helpers/driver_helper' require_relative '../deltacloud/helpers/auth_helper' -require_relative '../deltacloud/helpers/url_helper' require_relative '../deltacloud/helpers/deltacloud_helper' require_relative '../deltacloud/helpers/rabbit_helper' require_relative './helpers/cimi_helper' diff --git a/server/lib/cimi/models/cloud_entry_point.rb b/server/lib/cimi/models/cloud_entry_point.rb index 52997e7..f623798 100644 --- a/server/lib/cimi/models/cloud_entry_point.rb +++ b/server/lib/cimi/models/cloud_entry_point.rb @@ -26,7 +26,7 @@ class CIMI::Model::CloudEntryPoint < CIMI::Model::Base :name => context.driver.name, :description => "Cloud Entry Point for the Deltacloud #{context.driver.name} driver", :id => context.cloudEntryPoint_url, - :base_uri => context.root_url, + :base_uri => context.base_uri, :created => Time.now, :entity_metadata => CIMI::Model::EntityMetadata.all_uri(context) })) diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb index dc7c1ba..86aaf3c 100644 --- a/server/lib/cimi/server.rb +++ b/server/lib/cimi/server.rb @@ -43,6 +43,8 @@ module CIMI include CIMI::Collections include CIMI::Model + helpers Sinatra::Rabbit::URLFor(CIMI.collections) + get '/' do redirect url('/cloudEntryPoint'), 301 end diff --git a/server/lib/deltacloud/collections.rb b/server/lib/deltacloud/collections.rb index 7c18e09..df42cf1 100644 --- a/server/lib/deltacloud/collections.rb +++ b/server/lib/deltacloud/collections.rb @@ -49,7 +49,9 @@ module Deltacloud def self.included(klass) klass.class_eval do - Deltacloud::Collections.deltacloud_modules.each { |c| use c } + Deltacloud::Collections.deltacloud_modules.each do |collection_class| + use collection_class + end end end diff --git a/server/lib/deltacloud/collections/base.rb b/server/lib/deltacloud/collections/base.rb index d64c265..1cbeb70 100644 --- a/server/lib/deltacloud/collections/base.rb +++ b/server/lib/deltacloud/collections/base.rb @@ -21,9 +21,8 @@ module Deltacloud::Collections helpers Deltacloud::Helpers::Drivers helpers Sinatra::AuthHelper - helpers Sinatra::UrlForHelper helpers Deltacloud::Helpers::Application - + helpers Sinatra::Rabbit::URLHelper register Rack::RespondTo enable :xhtml diff --git a/server/lib/deltacloud/core_ext/hash.rb b/server/lib/deltacloud/core_ext/hash.rb index 52c6e89..c3f1a2f 100644 --- a/server/lib/deltacloud/core_ext/hash.rb +++ b/server/lib/deltacloud/core_ext/hash.rb @@ -35,4 +35,12 @@ class Hash self end + def to_query_params + return '' if empty? + '?' + self.map do |k,v| + next if k.nil? + "#{k}=#{URI.escape(v.to_s.strip, /[^#{URI::PATTERN::UNRESERVED}]/)}" + end.compact.join('&') + end + end diff --git a/server/lib/deltacloud/core_ext/string.rb b/server/lib/deltacloud/core_ext/string.rb index 483fe33..6838d6d 100644 --- a/server/lib/deltacloud/core_ext/string.rb +++ b/server/lib/deltacloud/core_ext/string.rb @@ -77,6 +77,11 @@ class String self.gsub(/;([^\/]*)/, '').gsub(/\?(.*)$/, '') end + def convert_query_params(params={}) + gsub(/:(\w+)/) { |p| params.delete(p[1..-1].to_sym) } + + params.to_query_params + end + unless "".respond_to? :each alias :each :each_line end diff --git a/server/lib/deltacloud/helpers.rb b/server/lib/deltacloud/helpers.rb index a97161c..d7680c1 100644 --- a/server/lib/deltacloud/helpers.rb +++ b/server/lib/deltacloud/helpers.rb @@ -15,7 +15,6 @@ require_relative 'helpers/driver_helper' require_relative 'helpers/auth_helper' -require_relative 'helpers/url_helper' require_relative 'helpers/deltacloud_helper' require_relative 'helpers/rabbit_helper' require_relative 'helpers/blob_stream_helper' diff --git a/server/lib/deltacloud/helpers/rabbit_helper.rb b/server/lib/deltacloud/helpers/rabbit_helper.rb index d6a472a..ef8080f 100644 --- a/server/lib/deltacloud/helpers/rabbit_helper.rb +++ b/server/lib/deltacloud/helpers/rabbit_helper.rb @@ -32,3 +32,50 @@ Sinatra::Rabbit::Collection.class_eval do end +module Sinatra::Rabbit + + module URLHelper + def url_for(path); url(path); end + def root_url; settings.root_url; end + def base_uri; url_for('/').gsub(/\/$/,''); end + end + + def self.URLFor(collections) + collections.each do |c| + c.operations.each do |operation| + URLHelper.instance_eval(&generate_url_helper_for(c, operation)[0]) + end + end + URLHelper + end + + def self.generate_url_helper_for(collection, operation) + operation_name = operation.operation_name.to_s + collection_name = collection.collection_name.to_s + + # Construct OPERATION_COLLECTION_URL helper + # The :index and :create operation does not get any prefix + # + helper_method_name = case operation_name + when 'index' then collection_name + when 'show' then collection_name.singularize + else operation_name + '_' + collection_name.singularize + end + + helper_method_name += '_url' + [Proc.new do + define_method helper_method_name do |*args| + if (opts = args.first).kind_of? Hash + path = operation.full_path.convert_query_params(opts) + elsif !args.empty? and (obj_id = args.first) + path = operation.full_path.convert_query_params(:id => obj_id) + else + path = operation.full_path + end + path.slice!(root_url) + url(path) + end unless respond_to?(helper_method_name) + end, helper_method_name] + end + +end diff --git a/server/lib/deltacloud/helpers/url_helper.rb b/server/lib/deltacloud/helpers/url_helper.rb deleted file mode 100644 index 1b084d4..0000000 --- a/server/lib/deltacloud/helpers/url_helper.rb +++ /dev/null @@ -1,115 +0,0 @@ -# -# Based on https://github.com/emk/sinatra-url-for/ -# Commit 1df339284203f8f6ed8d -# -# Original license: -# Copyright (C) 2009 Eric Kidd -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to permit -# persons to whom the Software is furnished to do so, subject to the -# following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -# USE OR OTHER DEALINGS IN THE SOFTWARE. - -module Sinatra - module UrlForHelper - - require 'uri' - - def method_missing(name, *args) - if name.to_s =~ /^([\w\_]+)_url$/ - if args.size > 0 - t = $1 - if t.match(/^(stop|reboot|start|attach|detach)_/) - action = $1 - api_url_for(t.pluralize.split('_').last + '/' + args.first.to_s + '/' + action, :full) - elsif t.match(/^(destroy|update)_/) - api_url_for(t.pluralize.split('_').last + '/' + args.first.to_s, :full) - else - api_url_for(t.pluralize, :full) + '/' + "#{args.first}" - end - else - api_url_for($1, :full) - end - else - super - end - end - - def api_url_for(url_fragment, mode=:path_only) - matrix_params = '' - if request.params['api'] - matrix_params += ";provider=%s" % request.params['api']['provider'] if request.params['api']['provider'] - matrix_params += ";driver=%s" % request.params['api']['driver'] if request.params['api']['driver'] - end - url_fragment = "/#{url_fragment}" unless url_fragment =~ /^\// # There is no need to prefix URI with '/' - if mode == :path_only - url_for "#{settings.root_url}#{matrix_params}#{url_fragment}", mode - else - url_for "#{matrix_params}#{url_fragment}", :full - end - end - - # Construct a link to +url_fragment+, which should be given relative to - # the base of this Sinatra app. The mode should be either - # <code>:path_only</code>, which will generate an absolute path within - # the current domain (the default), or <code>:full</code>, which will - # include the site name and port number. (The latter is typically - # necessary for links in RSS feeds.) Example usage: - # - # url_for "/" # Returns "/myapp/" - # url_for "/foo" # Returns "/myapp/foo" - # url_for "/foo", :full # Returns "http://example.com/myapp/foo" - #-- - # See README.rdoc for a list of some of the people who helped me clean - # up earlier versions of this code. - def url_for url_fragment, mode=:path_only - case mode - when :path_only - base = request.script_name.empty? ? Deltacloud.default_frontend.root_url : request.script_name - when :full - scheme = request.scheme - port = request.port - request_host = request.host - if request.env['HTTP_X_FORWARDED_FOR'] - scheme = request.env['HTTP_X_FORWARDED_SCHEME'] || scheme - port = request.env['HTTP_X_FORWARDED_PORT'] - request_host = request.env['HTTP_X_FORWARDED_HOST'] - end - if (port.nil? || port == "" || - (scheme == 'http' && port.to_s == '80') || - (scheme == 'https' && port.to_s == '443')) - port = "" - else - port = ":#{port}" - end - base = "#{scheme}://#{request_host}#{port}#{request.script_name.empty? ? settings.config.root_url : request.script_name}" - else - raise TypeError, "Unknown url_for mode #{mode}" - end - uri_parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI - url_escape = uri_parser.escape(url_fragment) - # Don't add the base fragment if url_for gets called more than once - # per url or the url_fragment passed in is an absolute url - if url_escape.match(/^#{base}/) or url_escape.match(/^http/) - url_escape - else - "#{base}#{url_escape}" - end - end - end - -end diff --git a/server/lib/deltacloud/server.rb b/server/lib/deltacloud/server.rb index c7c6c41..089fdfe 100644 --- a/server/lib/deltacloud/server.rb +++ b/server/lib/deltacloud/server.rb @@ -41,6 +41,8 @@ module Deltacloud include Deltacloud::Helpers include Deltacloud::Collections + helpers Sinatra::Rabbit::URLFor(Deltacloud.collections) + set :config, Deltacloud[:deltacloud] get '/' do -- 1.7.12
