Resource metadata
# File lib/cimi/service/base.rb, line 41 def collection_name name.split('::').last.underscore.pluralize.to_sym end
# File lib/cimi/service/base.rb, line 130 def self.create_url(ctx) cimi_create = "create_#{model_name}_url" dcloud_create = ctx.deltacloud_create_method_for(model_name) if(ctx.respond_to?(cimi_create) && ctx.driver.respond_to?(dcloud_create)) || provides?(model_name) ctx.send(cimi_create) end end
# File lib/cimi/service/base.rb, line 45 def inherited(subclass) # Decorate all the attributes of the model class schema = subclass.model_class.schema schema.attribute_names.each do |name| define_method(name) { self[name] } define_method(:"#{name}=") { |newval| self[name] = newval } end end
# File lib/cimi/service/base.rb, line 121 def self.list(ctx) id = ctx.send("#{collection_name}_url") entries = find(:all, ctx) params = {} params[:desc] = "#{self.name.split("::").last} Collection for the #{ctx.driver.name.capitalize} driver" params[:add_url] = create_url(ctx) model_class.list(id, entries, params).select_by(ctx.params['$select']).filter_by(ctx.params['$filter']) end
Define the metadata for an attribute; opts
must be a Hash that can contain the following entries:
:type : one of METADATA_TYPES :constraints : a proc that is passed the current context and must return a list of values
# File lib/cimi/service/base.rb, line 180 def self.metadata(attr_name = nil, opts = nil) @metadata ||= {} return @metadata if attr_name.nil? && opts.nil? opts[:type] ||= 'text' opts[:type] = opts[:type].to_s opts[:constraints] ||= lambda { |_| [] } unless METADATA_TYPES.include?(opts[:type]) raise "Metadata type must be one of #{METADATA_TYPES.join(",")}" end metadata[attr_name] = opts end
# File lib/cimi/service/base.rb, line 33 def model_class CIMI::Model.const_get(name.split('::').last) end
# File lib/cimi/service/base.rb, line 37 def model_name name.split('::').last.underscore.to_sym end
# File lib/cimi/service/base.rb, line 62 def initialize(context, opts) if opts[:values] @model = model_class.new(opts[:values]) elsif opts[:model] @model = opts[:model] else @model = model_class.new({}) end @context = context retrieve_entity end
# File lib/cimi/service/base.rb, line 54 def parse(context) req = context.request model = model_class.parse(req.body, req.content_type) new(context, :model => model) end
# File lib/cimi/service/base.rb, line 106 def self.resolve(ref, ctx) model = nil if ref.href? name = ref.class.superclass.name.split('::').last service_class = CIMI::Service::const_get(name) id = ref.href.split('/').last model = service_class.find(id, ctx) else # FIXME: if ref.href? we need to overwrite # attributes in model with ones from ref as long as they are present model = ref end model end
A hash of the attributes that need to be mentioned in the given context
# File lib/cimi/service/base.rb, line 146 def self.resource_attributes(context) metadata.keys.map do |k| a = model_class.schema.attributes.find { |a| a.name == k } raise "No attribute named #{k} defined" unless a constr = metadata[k][:constraints].call(context) { :name => a.name, :namespace => "http://deltacloud.org/cimi/#{model_name}/#{a.name}", :type => metadata[k][:type], :required => a.required? ? 'true' : 'false', :constraints => constr.map { |v| { :value => v } } } end end
# File lib/cimi/service/base.rb, line 161 def self.resource_capabilities(context) cimi_object = model_name.to_s.pluralize.to_sym driver_class = context.driver.class (driver_class.features[cimi_object] || []).map do |cur| feat = CIMI::FakeCollection.feature(cur) values = driver_class.constraints[cimi_object][feat.name][:values] || [] { :name => feat.name.to_s.camelize, :uri => CMWG_NAMESPACE+"/capability/#{cimi_object.to_s.camelize.singularize}/#{feat.name.to_s.camelize}", :description => feat.description, :value => values.join(",") } end end
# File lib/cimi/service/base.rb, line 85 def [](a) @model[a] end
Decorate some model methods
# File lib/cimi/service/base.rb, line 79 def []=(a, v) v = (@model[a] = v) retrieve_entity if a == :id v end
Destroy the database attributes for this model
# File lib/cimi/service/base.rb, line 208 def destroy @entity.destroy self end
FIXME: Kludge around the fact that we do not have proper *Create objects that deserialize properties by themselves
# File lib/cimi/service/base.rb, line 215 def extract_properties!(data) h = {} if data['property'] # Data came from XML h = data['property'].inject({}) do |r,v| r[v['key']] = v['content'] r end elsif data['properties'] h = data['properties'] end property ||= {} property.merge!(h) end
# File lib/cimi/service/base.rb, line 74 def model_class self.class.model_class end
# File lib/cimi/service/base.rb, line 230 def ref_id(ref_url) ref_url.split('/').last if ref_url end
Lookup a reference and return the corresponding model
# File lib/cimi/service/base.rb, line 102 def resolve(ref) self.class.resolve(ref, context) end
Save the common attributes name, description, and properties to the database
# File lib/cimi/service/base.rb, line 199 def save if @entity before_save @entity.save end self end
# File lib/cimi/service/base.rb, line 97 def select_attributes(attr_list) @model.select_attributes(attr_list) end
# File lib/cimi/service/base.rb, line 93 def to_json @model.to_json end
# File lib/cimi/service/base.rb, line 89 def to_xml @model.to_xml end
# File lib/cimi/service/base.rb, line 245 def after_retrieve attributes_to_copy.each { |a| @model[a] = @entity[a] } @model.property ||= {} @model.property.merge!(@entity.properties) end
# File lib/cimi/service/base.rb, line 236 def attributes_to_copy [:name, :description] end
# File lib/cimi/service/base.rb, line 240 def before_save attributes_to_copy.each { |a| @entity[a] = @model[a] } @entity.properties = @model.property end