You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by mf...@apache.org on 2013/02/22 11:32:24 UTC

[3/12] git commit: CIMI: Initial addition of attribute validation for CIMI models

CIMI: Initial addition of attribute validation for CIMI models

This addition will make possible to specify the 'required => true'
option for all attributes in CIMI models, like:

class Machine < Base
  text :name, :required => true
end

To run a check if the instance of Machine is valid or not you can do
following:

Machine.from_xml(xml_body).validate!

This method will raise the CIMI::Model::ValidationError exception if
attribute marked as 'required' have no value set.


Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/bcd5c45f
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/bcd5c45f
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/bcd5c45f

Branch: refs/heads/master
Commit: bcd5c45f3a34db7d2c224fef073ed2a7ac3a1a1c
Parents: 0ffdf17
Author: Michal Fojtik <mf...@redhat.com>
Authored: Thu Feb 7 13:32:44 2013 +0100
Committer: Michal fojtik <mf...@redhat.com>
Committed: Thu Feb 21 15:31:31 2013 +0100

----------------------------------------------------------------------
 server/lib/cimi/models/base.rb     |   26 ++++++++++++++++++++++++++
 server/lib/cimi/models/resource.rb |    4 ++++
 server/lib/cimi/models/schema.rb   |   22 ++++++++++++++++++++--
 3 files changed, 50 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltacloud/blob/bcd5c45f/server/lib/cimi/models/base.rb
----------------------------------------------------------------------
diff --git a/server/lib/cimi/models/base.rb b/server/lib/cimi/models/base.rb
index 80b645b..4341d4c 100644
--- a/server/lib/cimi/models/base.rb
+++ b/server/lib/cimi/models/base.rb
@@ -78,6 +78,24 @@ require_relative '../helpers/database_helper'
 
 module CIMI::Model
 
+  class ValidationError < StandardError
+
+    def initialize(attribute)
+      @attr_name  = attribute
+      super("Required attribute '#{@attr_name}' must be set.")
+    end
+
+    # Report the ValidationError as HTTP 400 - Bad Request
+    def code
+      400
+    end
+
+    def name
+      @attr_name
+    end
+
+  end
+
   class Base < Resource
 
     # Extend the base model with database methods
@@ -123,6 +141,14 @@ module CIMI::Model
       self
     end
 
+    def validate!(format=:xml)
+      self.class.required_attributes.each do |attr|
+        unless attr.valid?(send(attr.name))
+          raise CIMI::Model::ValidationError.new(attr.send("#{format}_name"))
+        end
+      end
+    end
+
     # FIXME: Kludge around the fact that we do not have proper *Create
     # objects that deserialize properties by themselves
     def extract_properties!(data)

http://git-wip-us.apache.org/repos/asf/deltacloud/blob/bcd5c45f/server/lib/cimi/models/resource.rb
----------------------------------------------------------------------
diff --git a/server/lib/cimi/models/resource.rb b/server/lib/cimi/models/resource.rb
index 3271c5e..d7eceec 100644
--- a/server/lib/cimi/models/resource.rb
+++ b/server/lib/cimi/models/resource.rb
@@ -145,6 +145,10 @@ module CIMI
           xml["resourceURI"] = resource_uri
           XmlSimple.xml_out(xml, :root_name => xml_tag_name)
         end
+
+        def required_attributes
+          @schema.required_attributes
+        end
       end
 
       # END of class methods

http://git-wip-us.apache.org/repos/asf/deltacloud/blob/bcd5c45f/server/lib/cimi/models/schema.rb
----------------------------------------------------------------------
diff --git a/server/lib/cimi/models/schema.rb b/server/lib/cimi/models/schema.rb
index 5a5d2c9..7260b81 100644
--- a/server/lib/cimi/models/schema.rb
+++ b/server/lib/cimi/models/schema.rb
@@ -24,11 +24,13 @@ class CIMI::Model::Schema
   #
   class Attribute
     attr_reader :name, :xml_name, :json_name
+    attr_reader :required
 
     def initialize(name, opts = {})
       @name = name
       @xml_name = opts[:xml_name] || name.to_s.camelize(true)
       @json_name = opts[:json_name] || name.to_s.camelize(true)
+      @required = opts[:required] || false
     end
 
     def from_xml(xml, model)
@@ -50,6 +52,14 @@ class CIMI::Model::Schema
     def convert(value)
       value
     end
+
+    def required?
+      @required
+    end
+
+    def valid?(value)
+      !value.nil? and !value.empty?
+    end
   end
 
   class Scalar < Attribute
@@ -122,7 +132,7 @@ class CIMI::Model::Schema
       else
         @schema = CIMI::Model::Schema.new
         @schema.instance_eval(&block) if block_given?
-        @schema.scalar(content, :text => :direct) if content
+        @schema.scalar(content, :text => :direct, :required => opts[:required]) if content
       end
     end
 
@@ -178,6 +188,10 @@ class CIMI::Model::Schema
       end
     end
 
+    def valid?(value)
+      @schema.required_attributes.any? { |a| a.valid?(value.send(a.name) )}
+    end
+
     private
     def struct
       if @klass
@@ -369,6 +383,10 @@ class CIMI::Model::Schema
     @attributes.map { |a| a.name }
   end
 
+  def required_attributes
+    @attributes.select { |a| a.required? }
+  end
+
   #
   # The DSL
   #
@@ -387,7 +405,7 @@ class CIMI::Model::Schema
 
     def href(*args)
       opts = args.extract_opts!
-      args.each { |arg| struct(arg, opts) { scalar :href } }
+      args.each { |arg| struct(arg, opts) { scalar :href, :required => opts[:required] } }
     end
 
     def text(*args)