You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by ma...@redhat.com on 2012/12/18 18:26:23 UTC

[PATCH 3/3] CIMI: Initial implementation of resource_metadata (capabilities) for Machine

From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/collections/resource_metadata.rb  |  2 +-
 server/lib/cimi/models/machine.rb                 |  9 ---
 server/lib/cimi/models/resource_metadata.rb       | 92 ++++++++++++++++-------
 server/lib/deltacloud/drivers/mock/mock_driver.rb |  9 +++
 4 files changed, 74 insertions(+), 38 deletions(-)

diff --git a/server/lib/cimi/collections/resource_metadata.rb b/server/lib/cimi/collections/resource_metadata.rb
index edd8d65..54de02a 100644
--- a/server/lib/cimi/collections/resource_metadata.rb
+++ b/server/lib/cimi/collections/resource_metadata.rb
@@ -32,7 +32,7 @@ module CIMI::Collections
       operation :show do
         description "Get the resource metadata for a specific collection"
         control do
-          resource_metadata = ResourceMetadata.find(params[:id], self)
+          resource_metadata = CIMI::Model::ResourceMetadata.find(params[:id], self)
           respond_to do |format|
             format.xml{resource_metadata.to_xml}
             format.json{resource_metadata.to_json}
diff --git a/server/lib/cimi/models/machine.rb b/server/lib/cimi/models/machine.rb
index 53bdd37..e9d774b 100644
--- a/server/lib/cimi/models/machine.rb
+++ b/server/lib/cimi/models/machine.rb
@@ -116,15 +116,6 @@ class CIMI::Model::Machine < CIMI::Model::Base
     context.driver.destroy_instance(context.credentials, id)
   end
 
-  def self.create_resource_metadata(context)
-    cimi_resource = self.name.split("::").last
-    metadata = CIMI::Model::ResourceMetadata.metadata_from_deltacloud_features(cimi_resource, :instances, context)
-    unless metadata.includes_attribute?(:name)
-      metadata.attributes << {:name=>"name", :required=>"false",
-                   :constraints=>"Determined by the cloud provider", :type=>"xs:string"}
-    end
-    metadata
-  end
   #returns the newly attach machine_volume
   def self.attach_volume(volume, location, context)
     context.driver.attach_storage_volume(context.credentials,
diff --git a/server/lib/cimi/models/resource_metadata.rb b/server/lib/cimi/models/resource_metadata.rb
index 5e62061..f216285 100644
--- a/server/lib/cimi/models/resource_metadata.rb
+++ b/server/lib/cimi/models/resource_metadata.rb
@@ -16,8 +16,12 @@
 
 class CIMI::Model::ResourceMetadata < CIMI::Model::Base
 
+  SCHEMA_CAPABILITY_BASE_URI = "http://schemas.dmtf.org/cimi/1/capability"
+
   acts_as_root_entity
 
+  text :name
+
   text :type_uri
 
   array :attributes do
@@ -25,10 +29,22 @@ class CIMI::Model::ResourceMetadata < CIMI::Model::Base
     scalar :namespace
     scalar :type
     scalar :required
-    scalar :constraints
+    array :constraints do
+      text :value
+    end
   end
 
-  array :operations do
+  array :capabilities do
+    scalar :name
+    scalar :uri
+    scalar :description
+    array :values do
+      text :value
+    end
+  end
+
+
+  array :actions do
     scalar :name
     scalar :uri
     scalar :description
@@ -37,49 +53,69 @@ class CIMI::Model::ResourceMetadata < CIMI::Model::Base
     scalar :output_message
   end
 
+  array :operations do
+    scalar :rel, :href
+  end
+
   def self.find(id, context)
-    resource_metadata = []
     if id == :all
+      resource_metadata = []
       CIMI::Model.root_entities.each do |resource_class|
-        resource_metadata << resource_class.create_resource_metadata(context) if resource_class.respond_to?(:create_resource_metadata)
+        meta = resource_metadata_for(resource_class, context)
+        resource_metadata << meta unless none_defined(meta)
       end
       return resource_metadata
     else
       resource_class = CIMI::Model.const_get("#{id.camelize}")
-      if resource_class.respond_to?(:create_resource_metadata)
-        resource_class.create_resource_metadata(context)
-      end
+      resource_metadata_for(resource_class, context)
     end
   end
 
-  def self.metadata_from_deltacloud_features(cimi_resource, dcloud_resource, context)
-    deltacloud_features = context.driver.class.features[dcloud_resource]
-    metadata_attributes = deltacloud_features.map{|f| attributes_from_feature(f)}
-    from_feature(cimi_resource, context, metadata_attributes.flatten!)
-  end
-
-  def includes_attribute?(attribute)
-    self.attributes.any?{|attr| attr[:name] == attribute}
+  def self.resource_metadata_for(resource_class, context)
+    attributes = rm_attributes_for(resource_class, context)
+    capabilities = rm_capabilities_for(resource_class, context)
+    actions = rm_actions_for(resource_class, context)
+    cimi_resource = resource_class.name.split("::").last
+    self.new({ :id => context.resource_metadata_url(cimi_resource.underscore),
+              :name => cimi_resource,
+              :type_uri => context.send("#{cimi_resource.underscore}_url"),
+              :attributes => attributes,
+              :capabilities => capabilities,
+              :actions => actions
+    })
   end
 
   private
 
-  def self.attributes_from_feature(feature)
-    feature = CIMI::FakeCollection.feature(feature)
-    feature.operations.first.params_array.map do |p|
-      {
-        :name=> p.name,
-        :type=> "xs:string",
-        :required=> p.required? ? "true" : "false",
-        :constraints=> (feature.constraints.empty? ? (feature.description.nil? ? "" : feature.description): feature.constraints)
-      }
+  def self.rm_attributes_for(resource_class, context)
+    []
+  end
+
+  def self.rm_capabilities_for(resource_class,context)
+    cimi_object = resource_class.name.split("::").last.underscore.pluralize.to_sym
+    capabilities = (context.driver.class.features[cimi_object] || []).inject([]) do |res, cur|
+      feat = CIMI::FakeCollection.feature(cur)
+      feat_param = feat.operations.first.params_array.first
+      values = (context.driver.class.constraints[cimi_object][feat.name][:values] || []).inject([]) do |vals, val|
+        vals << {:value => val}
+        vals
+      end
+      res << {:name => feat_param.name.to_s.camelize,
+       :uri => SCHEMA_CAPABILITY_BASE_URI+"/#{cimi_object.to_s.camelize.singularize}/#{feat_param.name.to_s.camelize}",
+       :description => feat_param.description,
+       :values => values }
+      res
     end
+#cimi_resource.underscore.pluralize.to_sym
+  end
+
+  def self.rm_actions_for(resource_class, context)
+    []
   end
 
-  def self.from_feature(cimi_resource, context, metadata_attributes)
-    self.new(:name => cimi_resource, :uri=>"#{context.resource_metadata_url}/#{cimi_resource.underscore}",
-             :type_uri=> context.send("#{cimi_resource.pluralize.underscore}_url"),
-             :attributes => metadata_attributes)
+  def self.none_defined(metadata)
+    return true if metadata.capabilities.empty? && metadata.capabilities.empty? && metadata.attributes.empty?
+    return false
   end
 
 end
diff --git a/server/lib/deltacloud/drivers/mock/mock_driver.rb b/server/lib/deltacloud/drivers/mock/mock_driver.rb
index 111196f..38cb042 100644
--- a/server/lib/deltacloud/drivers/mock/mock_driver.rb
+++ b/server/lib/deltacloud/drivers/mock/mock_driver.rb
@@ -84,6 +84,15 @@ module Deltacloud::Drivers::Mock
     feature :images, :user_name
     feature :images, :user_description
 
+    #cimi features
+    feature :machines, :default_initial_state do
+      { :values => ["STARTED"] }
+    end
+    feature :machines, :initial_states do
+      { :values => ["STARTED", "STOPPED"]}
+    end
+
+
     def initialize
       if ENV["DELTACLOUD_MOCK_STORAGE"]
         storage_root = ENV["DELTACLOUD_MOCK_STORAGE"]
-- 
1.7.11.7