Class: CIMI::Service::Base

Inherits:
Object
  • Object
show all
Extended by:
Deltacloud::Helpers::Database
Defined in:
lib/cimi/service/base.rb

Constant Summary collapse

METADATA_TYPES =

Resource metadata

[ 'text', 'URI', 'string', 'boolean' ]

Constants included from Deltacloud::Helpers::Database

Deltacloud::Helpers::Database::DATABASE_COLLECTIONS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Deltacloud::Helpers::Database

current_db, current_provider, provides?

Methods included from Deltacloud::Helpers::Drivers

#driver, #driver_class, #driver_class_name, #driver_name, #driver_source_name, #driver_symbol, included, #provider_name

Constructor Details

#initialize(context, opts) ⇒ Base

Returns a new instance of Base.

[View source]

62
63
64
65
66
67
68
69
70
71
72
# 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

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.


30
31
32
# File 'lib/cimi/service/base.rb', line 30

def context
  @context
end

#modelObject (readonly)

Returns the value of attribute model.


30
31
32
# File 'lib/cimi/service/base.rb', line 30

def model
  @model
end

Class Method Details

.collection_nameObject

[View source]

41
42
43
# File 'lib/cimi/service/base.rb', line 41

def collection_name
  name.split('::').last.underscore.pluralize.to_sym
end

.create_url(ctx) ⇒ Object

[View source]

130
131
132
133
134
135
136
137
# 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

.inherited(subclass) ⇒ Object

[View source]

45
46
47
48
49
50
51
52
# 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

.list(ctx) ⇒ Object

[View source]

121
122
123
124
125
126
127
128
# 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

.metadata(attr_name = nil, opts = nil) ⇒ Object

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
[View source]

180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/cimi/service/base.rb', line 180

def self.(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
  [attr_name] = opts
end

.model_classObject

[View source]

33
34
35
# File 'lib/cimi/service/base.rb', line 33

def model_class
  CIMI::Model.const_get(name.split('::').last)
end

.model_nameObject

[View source]

37
38
39
# File 'lib/cimi/service/base.rb', line 37

def model_name
  name.split('::').last.underscore.to_sym
end

.parse(context) ⇒ Object

[View source]

54
55
56
57
58
# 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

.resolve(ref, ctx) ⇒ Object

[View source]

106
107
108
109
110
111
112
113
114
115
116
117
118
119
# 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

.resource_attributes(context) ⇒ Object

A hash of the attributes that need to be mentioned in the given context

[View source]

146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/cimi/service/base.rb', line 146

def self.resource_attributes(context)
  .keys.map do |k|
    a = model_class.schema.attributes.find { |a| a.name == k }
    raise "No attribute named #{k} defined" unless a
    constr = [k][:constraints].call(context)
    {
      :name => a.name,
      :namespace => "http://deltacloud.org/cimi/#{model_name}/#{a.name}",
      :type => [k][:type],
      :required => a.required? ? 'true' : 'false',
      :constraints => constr.map { |v| { :value => v } }
    }
  end
end

.resource_capabilities(context) ⇒ Object

[View source]

161
162
163
164
165
166
167
168
169
170
171
172
173
# 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

Instance Method Details

#[](a) ⇒ Object

[View source]

85
86
87
# File 'lib/cimi/service/base.rb', line 85

def [](a)
  @model[a]
end

#[]=(a, v) ⇒ Object

Decorate some model methods

[View source]

79
80
81
82
83
# File 'lib/cimi/service/base.rb', line 79

def []=(a, v)
  v = (@model[a] = v)
  retrieve_entity if a == :id
  v
end

#destroyObject

Destroy the database attributes for this model

[View source]

208
209
210
211
# File 'lib/cimi/service/base.rb', line 208

def destroy
  @entity.destroy
  self
end

#extract_properties!(data) ⇒ Object

FIXME: Kludge around the fact that we do not have proper *Create objects that deserialize properties by themselves

[View source]

215
216
217
218
219
220
221
222
223
224
225
226
227
228
# 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

#model_classObject

[View source]

74
75
76
# File 'lib/cimi/service/base.rb', line 74

def model_class
  self.class.model_class
end

#ref_id(ref_url) ⇒ Object

[View source]

230
231
232
# File 'lib/cimi/service/base.rb', line 230

def ref_id(ref_url)
  ref_url.split('/').last if ref_url
end

#resolve(ref) ⇒ Object

Lookup a reference and return the corresponding model

[View source]

102
103
104
# File 'lib/cimi/service/base.rb', line 102

def resolve(ref)
  self.class.resolve(ref, context)
end

#saveObject

Save the common attributes name, description, and properties to the database

[View source]

199
200
201
202
203
204
205
# File 'lib/cimi/service/base.rb', line 199

def save
  if @entity
    before_save
    @entity.save
  end
  self
end

#select_attributes(attr_list) ⇒ Object

[View source]

97
98
99
# File 'lib/cimi/service/base.rb', line 97

def select_attributes(attr_list)
  @model.select_attributes(attr_list)
end

#to_jsonObject

[View source]

93
94
95
# File 'lib/cimi/service/base.rb', line 93

def to_json
  @model.to_json
end

#to_xmlObject

[View source]

89
90
91
# File 'lib/cimi/service/base.rb', line 89

def to_xml
  @model.to_xml
end