deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core 2/3] Core: Improved entity_url helper generation
Date Wed, 12 Sep 2012 09:01:29 GMT
From: Michal Fojtik <mfojtik@redhat.com>

* 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 <mfojtik@redhat.com>
---
 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


Mime
View raw message