You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2011/03/07 13:48:06 UTC

Matrix parameters (rev 2)

Hi,

I reworked MatrixParams as David propose and did it in a way how they
should behave. So now you can construct URIs like:

http://localhost:3001/api;v=0.1/images

=> params['api']['v'] = '0.1'

You can imagine how many possibilities this will open for us :-)

As an example I did a new way how to switch driver using URL:

deltacloudd -i mock
GET http://localhost:3001/api;driver=ec2/hardware_profiles

Will return EC2 hardware profiles. Basicaly it just add proper headers
using matrix param.

  -- Michal



Re: [PATCH core 1/2] Rack::MatrixParams now support all HTTP methods and are parsed as real matrix params (params can be defined for every URL component)

Posted by Michal Fojtik <mf...@redhat.com>.
On Mar 11, 2011, at 12:04 AM, David Lutterkort wrote:

> On Mon, 2011-03-07 at 13:48 +0100, mfojtik@redhat.com wrote:
>> From: Michal Fojtik <mf...@redhat.com>
>> 
>> ---
>> server/lib/sinatra/rack_matrix_params.rb |   86 ++++++++++++++++++++++++++++++
>> server/server.rb                         |    4 +-
>> server/views/instances/show.xml.haml     |    2 +-
>> 3 files changed, 90 insertions(+), 2 deletions(-)
>> create mode 100644 server/lib/sinatra/rack_matrix_params.rb
> 
> ACK, though it's missing unit tests :(


Test::Unit files included and pushed.

  -- Michal

> David
> 
> 

------------------------------------------------------
Michal Fojtik, mfojtik@redhat.com
Deltacloud API: http://deltacloud.org


Re: [PATCH core 1/2] Rack::MatrixParams now support all HTTP methods and are parsed as real matrix params (params can be defined for every URL component)

Posted by David Lutterkort <lu...@redhat.com>.
On Mon, 2011-03-07 at 13:48 +0100, mfojtik@redhat.com wrote:
> From: Michal Fojtik <mf...@redhat.com>
> 
> ---
>  server/lib/sinatra/rack_matrix_params.rb |   86 ++++++++++++++++++++++++++++++
>  server/server.rb                         |    4 +-
>  server/views/instances/show.xml.haml     |    2 +-
>  3 files changed, 90 insertions(+), 2 deletions(-)
>  create mode 100644 server/lib/sinatra/rack_matrix_params.rb

ACK, though it's missing unit tests :(

David



[PATCH core 1/2] Rack::MatrixParams now support all HTTP methods and are parsed as real matrix params (params can be defined for every URL component)

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>

---
 server/lib/sinatra/rack_matrix_params.rb |   86 ++++++++++++++++++++++++++++++
 server/server.rb                         |    4 +-
 server/views/instances/show.xml.haml     |    2 +-
 3 files changed, 90 insertions(+), 2 deletions(-)
 create mode 100644 server/lib/sinatra/rack_matrix_params.rb

diff --git a/server/lib/sinatra/rack_matrix_params.rb b/server/lib/sinatra/rack_matrix_params.rb
new file mode 100644
index 0000000..2858abe
--- /dev/null
+++ b/server/lib/sinatra/rack_matrix_params.rb
@@ -0,0 +1,86 @@
+# Copyright (C) 2011  Red Hat, Inc.
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# Methods added to this helper will be available to all templates in the application.
+
+module Rack
+
+  require 'cgi'
+
+  class MatrixParams
+    def initialize(app)
+      @app = app
+    end
+
+    # This will allow to use 'matrix' params in requests, like:
+    #
+    # http://example.com/library;section=nw/books;topic=money;binding=hardcover
+    #
+    # Will result in this params matrix:
+    #
+    # => params['library']['section'] = 'nw'
+    # => params['books']['topic'] = 'money'
+    # => params['books']['binding'] = 'hardcover'
+    #
+    # All HTTP methods are supported, in case of POST they will be passed as a
+    # regular <form> parameters.
+    
+    def call(env)
+      # Return if this header is not set properly (Rack::Test case...)
+      return @app.call(env) unless env['REQUEST_URI']
+
+      # Split URI to components and then extract ;var=value pairs
+      uri_components = env['REQUEST_URI'].split('/')
+      matrix_params = {}
+      uri_components.each do |component|
+	sub_components, value = component.split(/\;(\w+)\=/), nil
+	next unless sub_components.first  # Skip subcomponent if it's empty (usually /)
+	while param=sub_components.pop do
+	  if value
+	    matrix_params[sub_components.first] ||= {}
+	    matrix_params[sub_components.first].merge!(
+	      param => value
+	    )
+	    value=nil
+	    next
+	  else
+	    value = param
+	  end
+	end
+      end
+
+      # If request method is POST, simply include matrix params in form_hash
+      env['rack.request.form_hash'].merge!(matrix_params) if env['rack.request.form_hash']
+
+      # For other methods it's a way complicated ;-)
+      if env['REQUEST_METHOD']!='POST' and not matrix_params.keys.empty?
+	# Rewrite current path and query string and strip all matrix params from it
+	env['REQUEST_PATH'], env['PATH_INFO'] = env['REQUEST_URI'].gsub(/;([^\/]*)/, '').gsub(/\?(.*)$/, '')
+	env['PATH_INFO'] = env['REQUEST_PATH']
+	env['QUERY_STRING'].gsub!(/;([^\/]*)/, '')
+	new_params = matrix_params.collect do |component, params|
+	  params.collect { |k,v| "#{component}[#{k}]=#{CGI::escape(v.to_s)}" }
+	end.flatten
+	# Add matrix params as a regular GET params
+	env['QUERY_STRING'] += '&' if not env['QUERY_STRING'].empty?
+	env['QUERY_STRING'] += "#{new_params.join('&')}"
+      end
+      @app.call(env)
+    end
+  end
+
+end
diff --git a/server/server.rb b/server/server.rb
index 2618a9c..7eba0ae 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -30,15 +30,17 @@ require 'lib/deltacloud/helpers/blob_stream'
 require 'sinatra/rack_driver_select'
 require 'sinatra/rack_runtime'
 require 'sinatra/rack_etag'
+require 'sinatra/rack_matrix_params'
 
 set :version, '0.2.0'
 
 include Deltacloud::Drivers
 set :drivers, Proc.new { driver_config }
 
-use Rack::DriverSelect
 use Rack::ETag
 use Rack::Runtime
+use Rack::MatrixParams
+use Rack::DriverSelect
 
 configure do
   set :raise_errors => false
diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml
index ca7e0c6..ec2751a 100644
--- a/server/views/instances/show.xml.haml
+++ b/server/views/instances/show.xml.haml
@@ -22,7 +22,7 @@
       - @instance.actions.compact.each do |instance_action|
         %link{:rel => instance_action, :method => instance_action_method(instance_action), :href => self.send("#{instance_action}_instance_url", @instance.id)}
       - if driver.respond_to?(:run_on_instance)
-        %link{:rel => 'run', :method => :post, :href => run_instance_url(@instance.id)}
+        %link{:rel => 'run', :method => :post, :href => "#{run_instance_url(@instance.id)};id=#{@instance.id}"}
   - if @instance.instance_variables.include?("@launch_time")
     %launch_time<
       =@instance.launch_time
-- 
1.7.4


Re: [PATCH core 2/2] Added an option to switch driver using matrix params

Posted by David Lutterkort <lu...@redhat.com>.
On Mon, 2011-03-07 at 13:48 +0100, mfojtik@redhat.com wrote:
> From: Michal Fojtik <mf...@redhat.com>
> 
> ---
>  server/lib/sinatra/rack_driver_select.rb |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)

ACK



[PATCH core 2/2] Added an option to switch driver using matrix params

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>

---
 server/lib/sinatra/rack_driver_select.rb |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/server/lib/sinatra/rack_driver_select.rb b/server/lib/sinatra/rack_driver_select.rb
index 4acaf27..67d30e6 100644
--- a/server/lib/sinatra/rack_driver_select.rb
+++ b/server/lib/sinatra/rack_driver_select.rb
@@ -31,11 +31,19 @@ module Rack
 
     def call(env)
       original_settings = { }
+      req = Rack::Request.new(env)
+      if req.params['api'] and req.params['api']['driver']
+	env['HTTP_X_DELTACLOUD_DRIVER'] = req.params['api']['driver']
+      end
+      if req.params['api'] and req.params['api']['provider']
+	env['HTTP_X_DELTACLOUD_PROVIDER'] = req.params['api']['provider']
+      end
       HEADER_TO_ENV_MAP.each do |header, name|
         original_settings[name] = Thread.current[name]
         new_setting = extract_header(env, header)
         Thread.current[name] = new_setting if new_setting
       end
+
       @app.call(env)
     ensure
       original_settings.each { |name, value| Thread.current[name] = value }
-- 
1.7.4