incubator-deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Lutterkort <lut...@redhat.com>
Subject Re: DeltaCloud questions
Date Tue, 09 Aug 2011 22:59:27 GMT
On Tue, 2011-08-09 at 16:32 -0400, Tong Li wrote:
> 
> I am trying to figure out how DC works and I kept looking at the code in
> rabbit.rb and server.rb. I had hard time in the last couple of days
> figuring out what the following code does and how it does it. Please shed
> some lights. thanks.
> 
> here are the code that I could not get a handle of.
> 
>     control do
>       driver.destroy_storage_snapshot(credentials, params)
>       respond_to do |format|
>         format.xml { return 204 }
>         format.json { return 204 }
>         format.html { return redirect(storage_snapshots_url) }
>       end
>     end

In English, this code calls destroy_storage_snapshot in the currently
selected driver, then produces an XML, JSON or HTML response depending
on the Accept header the user sent.

Driver selection happens ultimately through a Rack middleware,
server/lib/sinatra/rack_driver_select.rb, and the driver method used in
the Sinatra::Application comes from server/lib/drivers.rb (which should
really go into server/lib/deltacloud)

Now to the respond_to business, which mimicks the respond_to in Rails:

> 
>  def respond_to(&block)
>        wants = {}
> 
>         def wants.method_missing(type, *args, &handler)
>           self[type] = handler
>         end
> 
>         # Set proper content-type and encoding for
>         # text based formats
>         puts format.inspect
>         if [:xml, :gv, :html, :json].include?(format)
>           content_type format, :charset => 'utf-8'
>         end
>         yield wants
>         # Raise this error if requested format is not defined
>         # in respond_to { } block.
>         raise MissingTemplate if wants[format].nil?
> 
>         wants[format].call
>       end
> 
> control block gets called when a request is received, then it calls
> respond_to method. respond_to method sets the variable "wants" to be an
> empty hash first, then yield to the code
> 
>         format.xml { return 204 }
>         format.json { return 204 }
>         format.html { return redirect(storage_snapshots_url) }
> 
> What puzzled me is how that hash gets member of xml, json and html, and
> where and how each member was set up as a proc or method?

The 'yield wants' runs the respond_to block with format bound to wants;
the line 'format.xml { ... }' then calls the 'xml' method on wants, with
'{ ... }' as the block. Since wants has no xml method, method_missing is
called, which stores the block (as a proc). Ultimately, 'format.xml
{ ... }' is executed as 'wants[:xml] = Proc.new { ... }'

You definitely dived straight into the most head-scratching code in
Deltacloud - the rest of the code is much more straightforward ;)

> I've also wrote a piece of code which tries to add a new URL
> like /api/john, here is my test code.
> 
> collection :john do
>   description <<EOS
> whatever this is just a test
> EOS
> 
>   operation :index do
>     description "list whatever"
>     control do
>       puts "came here anyway"
>       response.status = 200  # OK
>    end
>   end
> end
> 
> However, the code does not seem get executed when request
> (http://localhost:3001/api/john) was received. The browser will always
> return 404 error, it seems to me that I am missing some of the fundamentals
> of rabbit, please point out what I did wrong or missed.

You're running into the capability checking that Rabbit does. Since
different drivers support different collections and operations on them,
one of the things Rabbit does when it is asked to execute an operation
is to check whether the current backend driver supports that operation.
(Check the implementation of control on line 107 of rabbit.rb)

Since the driver you are using does not have a 'john' method, rabbit
raises the 404 (actually a Deltacloud::BackendCapability, see
lib/deltacloud/backend_capability.rb) before it even tries to run your
code.

David



Mime
View raw message