You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by Tong Li <li...@us.ibm.com> on 2011/08/09 22:32:40 UTC

DeltaCloud questions


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


 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?

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.

Thanks a lot.

Re: DeltaCloud questions

Posted by David Lutterkort <lu...@redhat.com>.
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