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