From: marios <[email protected]>

https://issues.apache.org/jira/browse/DTACLOUD-385

Signed-off-by: marios <[email protected]>
---
 server/lib/cimi/collections/volumes.rb | 11 +++-------
 server/lib/cimi/helpers/cimi_helper.rb | 39 ++++++++++++++++++++++++++++++----
 server/lib/cimi/models/volume.rb       | 37 +++++++++++++++++++-------------
 3 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/server/lib/cimi/collections/volumes.rb 
b/server/lib/cimi/collections/volumes.rb
index 32912c0..1078014 100644
--- a/server/lib/cimi/collections/volumes.rb
+++ b/server/lib/cimi/collections/volumes.rb
@@ -49,15 +49,10 @@ module CIMI::Collections
       operation :create, :with_capability => :create_storage_volume do
         description "Create a new Volume."
         control do
-          content_type = (request.content_type.end_with?("json") ? :json  : 
:xml)
-          #((request.content_type.end_with?("xml")) ? :xml : report_error(415) 
) FIXME
-          case content_type
-          when :json
-            new_volume = Volume.create_from_json(request.body.read, self)
-          when :xml
-            new_volume = Volume.create_from_xml(request.body.read, self)
-          end
+          content_type = grab_content_type(request.content_type, request.body)
+          new_volume = Volume.create(request.body.read, self, content_type)
           status 201
+          headers 'Location' => new_volume.id
           respond_to do |format|
             format.json { new_volume.to_json }
             format.xml { new_volume.to_xml }
diff --git a/server/lib/cimi/helpers/cimi_helper.rb 
b/server/lib/cimi/helpers/cimi_helper.rb
index 99af08a..9248f8a 100644
--- a/server/lib/cimi/helpers/cimi_helper.rb
+++ b/server/lib/cimi/helpers/cimi_helper.rb
@@ -34,22 +34,53 @@ module CIMI
     def to_kibibyte(value, unit)
       case unit
       when "GB"
-        (value.to_i*1024*1024).to_i
+        (value*1024*1024).to_i
       when "MB"
-        (value.to_i*1024).to_i
+        (value*1024).to_i
       else
         nil # should probably be exploding something here...
       end
     end
 
+    #e.g. convert volume to GB for deltacloud driver
     def from_kibibyte(value, unit="GB")
       case unit
-        when "GB" then ((value.to_i)/1024/1024).to_i
-        when "MB" then ((value.to_i)/1024).to_i
+        when "GB" then ((value.to_f)/1024/1024)
+        when "MB" then ((value.to_f)/1024)
         else nil
       end
     end
 
+    def grab_content_type(request_content_type, request_body)
+      case request_content_type
+        when /xml$/i then :xml
+        when /json$/i then :json
+        else guess_content_type(request_body)
+      end
+    end
+
+    def guess_content_type(request_body)
+      xml = json = false
+      body = request_body.read
+      request_body.rewind
+      begin
+        XmlSimple.xml_in(body)
+        xml = true
+      rescue Exception
+        xml = false
+      end
+      begin
+        JSON.parse(body)
+        json = true
+      rescue Exception
+        json = false
+      end
+      if (json == xml) #both true or both false
+        raise CIMI::Model::BadRequest.new("Couldn't guess content type of: 
#{body}")
+      end
+      type = (xml)? :xml : :json
+    end
+
   end
 end
 
diff --git a/server/lib/cimi/models/volume.rb b/server/lib/cimi/models/volume.rb
index 7951a99..8461f82 100644
--- a/server/lib/cimi/models/volume.rb
+++ b/server/lib/cimi/models/volume.rb
@@ -48,21 +48,24 @@ class CIMI::Model::Volume < CIMI::Model::Base
 
   def self.all(context); find(:all, context); end
 
-  def self.create_from_json(json_in, context)
-    json = JSON.parse(json_in)
-    volume_config_id = 
json["volumeTemplate"]["volumeConfig"]["href"].split("/").last
-    volume_image_id = (json["volumeTemplate"].has_key?("volumeImage") ?
-                json["volumeTemplate"]["volumeImage"]["href"].split("/").last  
: nil)
-    create_volume({:volume_config_id=>volume_config_id, 
:volume_image_id=>volume_image_id}, json, context)
+  def self.create(request_body, context, type)
+    #json = JSON.parse(json_in)
+    input = (type == :xml)? XmlSimple.xml_in(request_body, 
{"ForceArray"=>false,"NormaliseSpace"=>2}) : JSON.parse(request_body)
+    if input["volumeTemplate"]["href"]  #template by reference
+      #FIXME - don't have volumeTemplates yet - datamapper   volume_config =
+    else #template by value
+      volume_image_id = (input["volumeTemplate"].has_key?("volumeImage") ?
+                input["volumeTemplate"]["volumeImage"]["href"].split("/").last 
 : nil)
+      if input["volumeTemplate"]["volumeConfig"]["href"] #with config by 
reference
+        volume_config_id = 
input["volumeTemplate"]["volumeConfig"]["href"].split("/").last
+        create_volume({:volume_config_id=>volume_config_id, 
:volume_image_id=>volume_image_id}, input, context)
+      else #with config by value
+        capacity = input["volumeTemplate"]["volumeConfig"]["capacity"]
+        create_volume({:capacity=>capacity, 
:volume_image_id=>volume_image_id}, input, context)
+      end
+    end
   end
 
-  def self.create_from_xml(xml_in, context)
-    xml = XmlSimple.xml_in(xml_in)
-    volume_config_id = 
xml["volumeTemplate"][0]["volumeConfig"][0]["href"].split("/").last
-    volume_image_id = (xml["volumeTemplate"][0].has_key?("volumeImage") ?
-             
xml["volumeTemplate"][0]["volumeImage"][0]["href"].split("/").last  : nil)
-    create_volume({:volume_config_id=>volume_config_id, 
:volume_image_id=>volume_image_id}, xml, context)
-  end
 
   def self.delete!(id, context)
     context.driver.destroy_storage_volume(context.credentials, {:id=>id} )
@@ -88,8 +91,12 @@ class CIMI::Model::Volume < CIMI::Model::Base
   private
 
   def self.create_volume(params, data, context)
-    volume_config = 
CIMI::Model::VolumeConfiguration.find(params[:volume_config_id], context)
-    opts = {:capacity=>context.from_kibibyte(volume_config.capacity, "GB"), 
:snapshot_id=>params[:volume_image_id] }
+    if params[:volume_config_id]
+      volume_config = 
CIMI::Model::VolumeConfiguration.find(params[:volume_config_id], context)
+      opts = {:capacity=>context.from_kibibyte(volume_config.capacity, "GB"), 
:snapshot_id=>params[:volume_image_id] }
+    elsif params[:capacity]
+      opts = {:capacity=>context.from_kibibyte(params[:capacity], "GB"), 
:snapshot_id=>params[:volume_image_id]}
+    end
     storage_volume = context.driver.create_storage_volume(context.credentials, 
opts)
     store_attributes_for(context, storage_volume, data)
     from_storage_volume(storage_volume, context)
-- 
1.7.11.7

Reply via email to