You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2013/01/16 12:58:25 UTC
Replace datamapper with sequel (revision 2)
Hi,
This is a bit enhanced version of my previous patch set.
Additions/fixes:
- Added unit tests for database helper/schema (using in-memory sqlite)
- Added validation for entities (MachineTemplate, etc)
- Fixed false sqlite errors in console when launching with -V (verbose)
- Fixed wrong serialization for XML/JSON properties
- Fixed bug when creating new entity
Tracker: http://tracker.deltacloud.org/set/252
Cheers,
-- Michal
[PATCH core 7/8] Added validation to database models
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/db.rb | 7 +++++--
server/lib/db/address_template.rb | 7 +++++++
server/lib/db/machine_template.rb | 2 ++
server/lib/db/volume_configuration.rb | 2 ++
server/lib/db/volume_template.rb | 2 ++
5 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/server/lib/db.rb b/server/lib/db.rb
index c441021..6dc32c3 100644
--- a/server/lib/db.rb
+++ b/server/lib/db.rb
@@ -4,8 +4,11 @@ module Deltacloud
ENV['RACK_ENV'] == 'test'
end
- require 'sequel' unless test_environment?
- require 'logger'
+ unless test_environment?
+ require 'sequel'
+ require 'logger'
+ Sequel::Model.plugin :validation_class_methods
+ end
DATABASE_LOCATION = ENV['DATABASE_LOCATION'] ||
'sqlite://'+File.join('/', 'var', 'tmp', "deltacloud-mock-#{ENV['USER']}", 'db.sqlite')
diff --git a/server/lib/db/address_template.rb b/server/lib/db/address_template.rb
index 8586255..55771d1 100644
--- a/server/lib/db/address_template.rb
+++ b/server/lib/db/address_template.rb
@@ -2,6 +2,13 @@ module Deltacloud
module Database
class AddressTemplate < Entity
+ validates_presence_of :ip
+ validates_presence_of :hostname
+ validates_presence_of :allocation
+ validates_presence_of :default_gateway
+ validates_presence_of :dns
+ validates_presence_of :protocol
+ validates_presence_of :mask
end
end
diff --git a/server/lib/db/machine_template.rb b/server/lib/db/machine_template.rb
index 1b34161..61f57c1 100644
--- a/server/lib/db/machine_template.rb
+++ b/server/lib/db/machine_template.rb
@@ -2,6 +2,8 @@ module Deltacloud
module Database
class MachineTemplate < Entity
+ validates_presence_of :machine_config
+ validates_presence_of :machine_image
end
end
diff --git a/server/lib/db/volume_configuration.rb b/server/lib/db/volume_configuration.rb
index aa956ce..ebf59c2 100644
--- a/server/lib/db/volume_configuration.rb
+++ b/server/lib/db/volume_configuration.rb
@@ -2,6 +2,8 @@ module Deltacloud
module Database
class VolumeConfiguration < Entity
+ validates_presence_of :format
+ validates_presence_of :capacity
end
end
diff --git a/server/lib/db/volume_template.rb b/server/lib/db/volume_template.rb
index 0d876bf..8a4953a 100644
--- a/server/lib/db/volume_template.rb
+++ b/server/lib/db/volume_template.rb
@@ -2,6 +2,8 @@ module Deltacloud
module Database
class VolumeTemplate < Entity
+ validates_presence_of :volume_config
+ validates_presence_of :volume_Image
end
end
--
1.8.0.2
[PATCH core 5/8] CIMI: Moved database initialization to models.rb
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
This will allow proper testing of database
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/cimi/models.rb | 13 +++++++++++++
server/lib/cimi/server.rb | 2 --
server/lib/db.rb | 12 +-----------
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb
index 09c9552..356f5a7 100644
--- a/server/lib/cimi/models.rb
+++ b/server/lib/cimi/models.rb
@@ -18,6 +18,17 @@ module CIMI
end
require 'require_relative' if RUBY_VERSION < '1.9'
+require_relative '../db'
+
+unless Deltacloud.test_environment?
+ Deltacloud::initialize_database
+ require_relative './../db/provider'
+ require_relative './../db/entity'
+ require_relative './../db/machine_template'
+ require_relative './../db/address_template'
+ require_relative './../db/volume_configuration'
+ require_relative './../db/volume_template'
+end
require_relative './models/schema'
require_relative './models/base'
@@ -29,7 +40,9 @@ require_relative './models/disk'
require_relative './models/resource_metadata'
require_relative './models/cloud_entry_point'
+
CIMI::Model::ResourceMetadata.acts_as_root_entity
+
require_relative './models/volume'
require_relative './models/volume_template'
require_relative './models/volume_configuration'
diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index 41c8bd6..d23b949 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -20,8 +20,6 @@ require 'sinatra/base'
require 'sinatra/rabbit'
require_relative '../sinatra'
-require_relative '../db'
-
require_relative './helpers'
require_relative './collections'
diff --git a/server/lib/db.rb b/server/lib/db.rb
index 49e6f33..c441021 100644
--- a/server/lib/db.rb
+++ b/server/lib/db.rb
@@ -1,7 +1,7 @@
module Deltacloud
def self.test_environment?
- ENV['RACK_ENV'] == 'test' || ENV['DELTACLOUD_NO_DATABASE']
+ ENV['RACK_ENV'] == 'test'
end
require 'sequel' unless test_environment?
@@ -72,13 +72,3 @@ module Deltacloud
end
end
-
-unless Deltacloud.test_environment?
- Deltacloud::initialize_database
- require_relative './db/provider'
- require_relative './db/entity'
- require_relative './db/machine_template'
- require_relative './db/address_template'
- require_relative './db/volume_configuration'
- require_relative './db/volume_template'
-end
--
1.8.0.2
[PATCH core 1/8] CIMI: Replaced DataMapper with Sequel ORM
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/deltacloud-core.gemspec | 5 +-
server/lib/cimi/helpers/database_helper.rb | 19 +++++--
server/lib/db.rb | 81 +++++++++++++++++++++++-------
3 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/server/deltacloud-core.gemspec b/server/deltacloud-core.gemspec
index 7fad5be..977cc26 100644
--- a/server/deltacloud-core.gemspec
+++ b/server/deltacloud-core.gemspec
@@ -78,9 +78,8 @@ Gem::Specification.new do |s|
s.add_dependency('nokogiri', '>= 1.4.3')
s.add_dependency('require_relative') if RUBY_VERSION < '1.9'
- s.add_dependency('data_mapper')
- s.add_dependency('dm-sqlite-adapter')
- s.add_dependency('dm-timestamps')
+ s.add_dependency('sequel', '<= 3.42.0')
+ s.add_dependency('sqlite3')
# dependencies for various cloud providers:
diff --git a/server/lib/cimi/helpers/database_helper.rb b/server/lib/cimi/helpers/database_helper.rb
index ac6ae4f..d432f69 100644
--- a/server/lib/cimi/helpers/database_helper.rb
+++ b/server/lib/cimi/helpers/database_helper.rb
@@ -27,11 +27,14 @@ module Deltacloud
def delete_attributes_for(model)
return if test_environment?
entity = get_entity(model)
- !entity.nil? && entity.destroy!
+ !entity.nil? && entity.destroy
end
def get_entity(model)
- Deltacloud::Database::Entity.first(:be_kind => model.to_entity, :be_id => model.id, 'provider.driver' => driver_symbol.to_s, 'provider.url' => current_provider)
+ current_db.entities_dataset.first(
+ :be_kind => model.to_entity,
+ :be_id => model.id,
+ )
end
def current_provider
@@ -43,23 +46,29 @@ module Deltacloud
#
def current_db
- Deltacloud::Database::Provider.first_or_create(:driver => driver_symbol.to_s, :url => current_provider)
+ Deltacloud::Database::Provider.find_or_create(:driver => driver_symbol.to_s, :url => current_provider)
end
def store_attributes_for(model, attrs={})
return if test_environment? or model.nil? or attrs.empty?
return if model.id.nil?
- entity = get_entity(model) || current_db.entities.new(:be_kind => model.to_entity, :be_id => model.id)
+
+ unless entity = get_entity(model)
+ entity = Deltacloud::Database::Entity.new(:provider_id => current_db.id)
+ end
entity.description = extract_attribute_value('description', attrs) if attrs.has_key? 'description'
entity.name = extract_attribute_value('name', attrs) if attrs.has_key? 'name'
+
if attrs.has_key? 'properties'
entity.ent_properties = extract_attribute_value('properties', attrs).to_json
elsif attrs.has_key? 'property'
entity.ent_properties = extract_attribute_value('property', attrs).to_json
end
- entity.save && entity
+ entity.exists? ? entity.save_changes : entity.save
+
+ entity
end
# In XML serialization the values stored in attrs are arrays, dues to
diff --git a/server/lib/db.rb b/server/lib/db.rb
index 567b356..64cc283 100644
--- a/server/lib/db.rb
+++ b/server/lib/db.rb
@@ -4,27 +4,74 @@ module Deltacloud
ENV['RACK_ENV'] == 'test' || ENV['DELTACLOUD_NO_DATABASE']
end
- unless test_environment?
- require 'data_mapper'
- require_relative './db/provider'
- require_relative './db/entity'
- require_relative './db/machine_template'
- require_relative './db/address_template'
- require_relative './db/volume_configuration'
- require_relative './db/volume_template'
- end
+ require 'sequel' unless test_environment?
+ require 'logger'
+
+ DATABASE_LOCATION = ENV['DATABASE_LOCATION'] ||
+ 'sqlite://'+File.join('/', 'var', 'tmp', "deltacloud-mock-#{ENV['USER']}", 'db.sqlite')
- DATABASE_LOCATION = ENV['DATABASE_LOCATION'] || File.join('/', 'var', 'tmp', "deltacloud-mock-#{ENV['USER']}", 'db.sqlite')
+ def self.database(opts={})
+ opts[:logger] = ::Logger.new($stdout) if ENV['API_VERBOSE']
+ @db ||= Sequel.connect(DATABASE_LOCATION, opts)
+ end
def self.initialize_database
- DataMapper::Logger.new($stdout, :debug) if ENV['API_VERBOSE']
- dbdir = File::dirname(DATABASE_LOCATION)
- FileUtils::mkdir(dbdir) unless File::directory?(dbdir)
- DataMapper::setup(:default, "sqlite://#{DATABASE_LOCATION}")
- DataMapper::finalize
- DataMapper::auto_upgrade!
+
+ database.create_table?(:providers) {
+ primary_key :id
+
+ column :driver, :string, { :null => false }
+ column :url, :string
+ index [ :url, :driver ]
+ }
+
+ database.create_table?(:entities) {
+ primary_key :id
+ foreign_key :provider_id, :providers, { :index => true, :null => false }
+ column :created_at, :timestamp
+
+ # Base
+ column :model, :string, { :index => true, :null => false, :default => 'entity' }
+
+ # Map Entity to Deltacloud model
+ # (like: Machine => Instance)
+ column :be_kind, :string
+ column :be_id, :string
+
+ # Entity
+ column :name, :string
+ column :description, :string
+ column :ent_properties, :string, { :text => true }
+
+
+ column :machine_config, :string
+ column :machine_image, :string
+
+ column :network, :string
+ column :ip, :string
+ column :hostname, :string
+ column :allocation, :string
+ column :default_gateway, :string
+ column :dns, :string
+ column :protocol, :string
+ column :mask, :string
+
+ column :format, :string
+ column :capacity, :string
+
+ column :volume_config, :string
+ column :volume_image, :string
+ }
end
end
-Deltacloud::initialize_database unless Deltacloud.test_environment?
+unless Deltacloud.test_environment?
+ Deltacloud::initialize_database
+ require_relative './db/provider'
+ require_relative './db/entity'
+ require_relative './db/machine_template'
+ require_relative './db/address_template'
+ require_relative './db/volume_configuration'
+ require_relative './db/volume_template'
+end
--
1.8.0.2
[PATCH core 3/8] CIMI: Updated CIMI models to use Sequel methods and helpers
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/cimi/models/address_template.rb | 25 ++++------------
server/lib/cimi/models/machine.rb | 2 +-
server/lib/cimi/models/machine_template.rb | 25 ++++------------
server/lib/cimi/models/volume_configuration.rb | 25 ++++------------
server/lib/cimi/models/volume_template.rb | 40 ++++++++++----------------
5 files changed, 34 insertions(+), 83 deletions(-)
diff --git a/server/lib/cimi/models/address_template.rb b/server/lib/cimi/models/address_template.rb
index 2d81f23..1e28602 100644
--- a/server/lib/cimi/models/address_template.rb
+++ b/server/lib/cimi/models/address_template.rb
@@ -42,20 +42,13 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
if context.driver.respond_to? :address_templates
context.driver.address_templates(context.credentials, {:env=>context})
else
- Deltacloud::Database::AddressTemplate.all(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider
- ).map { |t| from_db(t, context) }
+ current_db.address_teplates.map { |t| from_db(t, context) }
end
else
if context.driver.respond_to? :address_template
context.driver.address_template(context.credentials, id, :env=>context)
else
- template = Deltacloud::Database::AddressTemplate.first(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider,
- :id => id
- )
+ template = current_db.address_templates_dataset.first(:id => id)
raise CIMI::Model::NotFound unless template
from_db(template, context)
end
@@ -64,7 +57,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
def self.create_from_json(body, context)
json = JSON.parse(body)
- new_template = current_db.address_templates.new(
+ new_template = current_db.add_address_template(
:name => json['name'],
:description => json['description'],
:hostname => json['hostname'],
@@ -75,17 +68,14 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
:protocol => json['protocol'],
:mask => json['mask'],
:ent_properties => json['properties'].to_json,
- :be_kind => 'address_template',
- :be_id => ''
)
- new_template.save
from_db(new_template, context)
end
def self.create_from_xml(body, context)
xml = XmlSimple.xml_in(body)
xml['property'] ||= []
- new_template = current_db.address_templates.new(
+ new_template = current_db.add_address_template(
:name => xml['name'].first,
:description => xml['description'].first,
:ip => xml['ip'].first,
@@ -95,11 +85,8 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
:dns => xml['dns'].first,
:protocol => xml['protocol'].nil? ? nil : xml['protocol'].first,
:mask => xml['mask'].first,
- :ent_properties => xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r },
- :be_kind => 'machine_template',
- :be_id => ''
+ :ent_properties => JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r }),
)
- new_template.save
from_db(new_template, context)
end
@@ -121,7 +108,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
:dns => model.dns,
:protocol => model.protocol,
:mask => model.mask,
- :property => model.ent_properties,
+ :property => JSON::parse(model.ent_properties),
:operations => [
{ :href => context.destroy_address_template_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
]
diff --git a/server/lib/cimi/models/machine.rb b/server/lib/cimi/models/machine.rb
index 7ac8f83..67e3eef 100644
--- a/server/lib/cimi/models/machine.rb
+++ b/server/lib/cimi/models/machine.rb
@@ -81,7 +81,7 @@ class CIMI::Model::Machine < CIMI::Model::Base
def self.create_from_xml(body, context)
xml = XmlSimple.xml_in(body)
if xml['machineTemplate'][0]['href']
- template = current_db.machine_templates.first(:id => xml['machineTemplate'][0]['href'].split('/').last)
+ template = current_db.machine_templates_dataset.first(:id => xml['machineTemplate'][0]['href'].split('/').last)
hardware_profile_id = template.machine_config.split('/').last
image_id = template.machine_image.split('/').last
else
diff --git a/server/lib/cimi/models/machine_template.rb b/server/lib/cimi/models/machine_template.rb
index eb660d2..675f709 100644
--- a/server/lib/cimi/models/machine_template.rb
+++ b/server/lib/cimi/models/machine_template.rb
@@ -44,16 +44,9 @@ class CIMI::Model::MachineTemplate < CIMI::Model::Base
class << self
def find(id, context)
if id == :all
- Deltacloud::Database::MachineTemplate.all(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider
- ).map { |t| from_db(t, context) }
+ current_db.machine_templates.map { |t| from_db(t, context) }
else
- template = Deltacloud::Database::MachineTemplate.first(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider,
- :id => id
- )
+ template = current_db.machine_templates_dataset.first(:id => id)
raise CIMI::Model::NotFound unless template
from_db(template, context)
end
@@ -61,31 +54,25 @@ class CIMI::Model::MachineTemplate < CIMI::Model::Base
def create_from_json(body, context)
json = JSON.parse(body)
- new_template = current_db.machine_templates.new(
+ new_template = current_db.add_machine_template(
:name => json['name'],
:description => json['description'],
:machine_config => json['machineConfig']['href'],
:machine_image => json['machineImage']['href'],
:ent_properties => json['properties'].to_json,
- :be_kind => 'machine_template',
- :be_id => ''
)
- new_template.save
from_db(new_template, context)
end
def create_from_xml(body, context)
xml = XmlSimple.xml_in(body)
- new_template = current_db.machine_templates.new(
+ new_template = current_db.add_machine_template(
:name => xml['name'].first,
:description => xml['description'].first,
:machine_config => xml['machineConfig'].first['href'],
:machine_image => xml['machineImage'].first['href'],
- :ent_properties => xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r },
- :be_kind => 'machine_template',
- :be_id => ''
+ :ent_properties => JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r }),
)
- new_template.save
from_db(new_template, context)
end
@@ -102,7 +89,7 @@ class CIMI::Model::MachineTemplate < CIMI::Model::Base
:description => model.description,
:machine_config => { :href => model.machine_config },
:machine_image => { :href => model.machine_image },
- :property => model.ent_properties,
+ :property => JSON::parse(model.ent_properties),
:created => Time.parse(model.created_at.to_s).xmlschema,
:operations => [
{ :href => context.destroy_machine_template_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
diff --git a/server/lib/cimi/models/volume_configuration.rb b/server/lib/cimi/models/volume_configuration.rb
index b0ba85b..12a3198 100644
--- a/server/lib/cimi/models/volume_configuration.rb
+++ b/server/lib/cimi/models/volume_configuration.rb
@@ -27,32 +27,26 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
def self.create_from_json(body, context)
json = JSON.parse(body)
- new_config = current_db.volume_configurations.new(
+ new_config = current_db.add_volume_configuration(
:name => json['name'],
:description => json['description'],
:format => json['format'],
:capacity => json['capacity'],
:ent_properties => json['properties'].to_json,
- :be_kind => 'volume_configuration',
- :be_id => ''
)
- new_config.save
from_db(new_config, context)
end
def self.create_from_xml(body, context)
xml = XmlSimple.xml_in(body)
xml['property'] ||= []
- new_config = current_db.volume_configurations.new(
+ new_config = current_db.add_volume_configuration(
:name => xml['name'].first,
:description => xml['description'].first,
:format => xml['format'].first,
:capacity => xml['capacity'].first,
- :ent_properties => xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r },
- :be_kind => 'volume_configuration',
- :be_id => ''
+ :ent_properties => JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r }),
)
- new_config.save
from_db(new_config, context)
end
@@ -65,20 +59,13 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
if context.driver.respond_to? :volume_configurations
context.driver.volume_configurations(context.credentials, {:env=>context})
else
- Deltacloud::Database::VolumeConfiguration.all(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider
- ).map { |t| from_db(t, context) }
+ current_db.volume_configurations.map { |t| from_db(t, context) }
end
else
if context.driver.respond_to? :volume_configuration
context.driver.volume_configuration(context.credentials, id, :env=>context)
else
- config = Deltacloud::Database::VolumeConfiguration.first(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider,
- :id => id
- )
+ config = current_db.volume_configurations_dataset.first(:id => id)
raise CIMI::Model::NotFound unless config
from_db(config, context)
end
@@ -94,7 +81,7 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
:description => model.description,
:format => model.format,
:capacity => context.to_kibibyte(model.capacity, "GB"),
- :property => model.ent_properties,
+ :property => JSON::parse(model.ent_properties),
:operations => [
{ :href => context.destroy_volume_configuration_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
]
diff --git a/server/lib/cimi/models/volume_template.rb b/server/lib/cimi/models/volume_template.rb
index a2b8eb7..47bbb3f 100644
--- a/server/lib/cimi/models/volume_template.rb
+++ b/server/lib/cimi/models/volume_template.rb
@@ -30,27 +30,20 @@ class CIMI::Model::VolumeTemplate < CIMI::Model::Base
end
def self.find(id, context)
- if id==:all
- if context.driver.respond_to? :volume_templates
- context.driver.volume_templates(context.credentials, {:env=>context})
- else
- Deltacloud::Database::VolumeTemplate.all(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider
- ).map { |t| from_db(t, context) }
+ if id==:all
+ if context.driver.respond_to? :volume_templates
+ context.driver.volume_templates(context.credentials, {:env=>context})
+ else
+ current_db.volume_templates.map { |t| from_db(t, context) }
end
else
- if context.driver.respond_to? :volume_template
- context.driver.volume_template(context.credentials, id, :env=>context)
- else
- template = Deltacloud::Database::VolumeTemplate.first(
- 'provider.driver' => driver_symbol.to_s,
- 'provider.url' => current_provider,
- :id => id
- )
- raise CIMI::Model::NotFound unless template
- from_db(template, context)
- end
+ if context.driver.respond_to? :volume_template
+ context.driver.volume_template(context.credentials, id, :env=>context)
+ else
+ template = current_db.volume_templates_dataset.first(:id => id)
+ raise CIMI::Model::NotFound unless template
+ from_db(template, context)
+ end
end
end
@@ -58,16 +51,13 @@ class CIMI::Model::VolumeTemplate < CIMI::Model::Base
input = (type == :xml)? XmlSimple.xml_in(body, {"ForceArray"=>false,"NormaliseSpace"=>2}) : JSON.parse(body)
input['property'] ||= []
vol_image = input['volumeImage']['href'] if input['volumeImage']
- new_template = current_db.volume_templates.new(
+ new_template = current_db.add_volume_template(
:name => input['name'],
:description => input['description'],
:volume_config => input['volumeConfig']['href'],
:volume_image => vol_image,
- :ent_properties => input['property'].inject({}) { |r, p| r[p['key']]=p['content']; r },
- :be_kind => 'volume_template',
- :be_id => ''
+ :ent_properties => JSON::dump(input['property'].inject({}) { |r, p| r[p['key']]=p['content']; r }),
)
- new_template.save
from_db(new_template, context)
end
@@ -84,7 +74,7 @@ private
:description => model.description,
:volume_config => {:href => model.volume_config},
:volume_image => {:href => model.volume_image},
- :property => model.ent_properties,
+ :property => JSON::parse(model.ent_properties),
:operations => [
{ :href => context.destroy_volume_template_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
]
--
1.8.0.2
[PATCH core 2/8] CIMI: Migrated database models to use Sequel
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/db/address_template.rb | 10 ---------
server/lib/db/entity.rb | 25 +++++----------------
server/lib/db/machine_template.rb | 5 -----
server/lib/db/provider.rb | 41 +++++------------------------------
server/lib/db/volume_configuration.rb | 4 ----
server/lib/db/volume_template.rb | 4 ----
6 files changed, 11 insertions(+), 78 deletions(-)
diff --git a/server/lib/db/address_template.rb b/server/lib/db/address_template.rb
index 5a08346..8586255 100644
--- a/server/lib/db/address_template.rb
+++ b/server/lib/db/address_template.rb
@@ -2,16 +2,6 @@ module Deltacloud
module Database
class AddressTemplate < Entity
- belongs_to :provider
-
- property :ip, String
- property :hostname, String
- property :allocation, String, :default => 'dynamic'
- property :default_gateway, String, :default => 'unknown'
- property :dns, String, :default => 'unknown'
- property :protocol, String, :default => 'ipv4'
- property :mask, String, :default => 'unknown'
- property :network, String
end
end
diff --git a/server/lib/db/entity.rb b/server/lib/db/entity.rb
index f9b34ff..963a26b 100644
--- a/server/lib/db/entity.rb
+++ b/server/lib/db/entity.rb
@@ -1,33 +1,18 @@
module Deltacloud
module Database
- class BaseEntity
- include DataMapper::Resource
+ class Entity < Sequel::Model
- belongs_to :provider
+ many_to_one :provider
- property :id, Serial
- property :type, Discriminator
-
- property :be_kind, String, :required => true # => Machine, MachineImage, ...
- property :be_id, String # => Original Machine 'id'
-
- timestamps :created_at, :updated_on
- end
-
- class Entity < BaseEntity
-
- belongs_to :provider
-
- property :name, String
- property :description, String
- property :ent_properties, Json
+ plugin :single_table_inheritance, :model
+ plugin :timestamps, :create => :created_at
def to_hash
retval = {}
retval.merge!(:name => self.name) if !self.name.nil?
retval.merge!(:description => self.description) if !self.description.nil?
- retval.merge!(:property => self.ent_properties) if !self.ent_properties.nil?
+ retval.merge!(:property => JSON::parse(self.ent_properties)) if !self.ent_properties.nil?
retval
end
diff --git a/server/lib/db/machine_template.rb b/server/lib/db/machine_template.rb
index 134eb23..1b34161 100644
--- a/server/lib/db/machine_template.rb
+++ b/server/lib/db/machine_template.rb
@@ -2,11 +2,6 @@ module Deltacloud
module Database
class MachineTemplate < Entity
- belongs_to :provider
-
- property :machine_config, String, :length => 255
- property :machine_image, String, :length => 255
-
end
end
diff --git a/server/lib/db/provider.rb b/server/lib/db/provider.rb
index e8ca4f5..c0b8485 100644
--- a/server/lib/db/provider.rb
+++ b/server/lib/db/provider.rb
@@ -1,41 +1,12 @@
module Deltacloud
module Database
- class Provider
- include DataMapper::Resource
-
- property :id, Serial
- property :driver, String, :required => true
- property :url, Text
-
- has n, :entities
- has n, :machine_templates
- has n, :address_templates
- has n, :volume_configurations
- has n, :volume_templates
-
- # This is a workaround for strange bug in Fedora MRI:
- #
- def machine_templates
- MachineTemplate.all(:provider_id => self.id)
- end
-
- def address_templates
- AddressTemplate.all(:provider_id => self.id)
- end
-
- def volume_configurations
- VolumeConfiguration.all(:provider_id => self.id)
- end
-
- def volume_templates
- VolumeTemplate.all(:provider_id => self.id)
- end
-
- def entities
- Entity.all(:provider_id => self.id)
- end
-
+ class Provider < Sequel::Model
+ one_to_many :entities
+ one_to_many :machine_templates
+ one_to_many :address_templates
+ one_to_many :volume_templates
+ one_to_many :volume_configurations
end
end
diff --git a/server/lib/db/volume_configuration.rb b/server/lib/db/volume_configuration.rb
index 58aa624..aa956ce 100644
--- a/server/lib/db/volume_configuration.rb
+++ b/server/lib/db/volume_configuration.rb
@@ -2,10 +2,6 @@ module Deltacloud
module Database
class VolumeConfiguration < Entity
- belongs_to :provider
-
- property :format, String
- property :capacity, String
end
end
diff --git a/server/lib/db/volume_template.rb b/server/lib/db/volume_template.rb
index 8658b8b..0d876bf 100644
--- a/server/lib/db/volume_template.rb
+++ b/server/lib/db/volume_template.rb
@@ -2,10 +2,6 @@ module Deltacloud
module Database
class VolumeTemplate < Entity
- belongs_to :provider
-
- property :volume_config, String
- property :volume_image, String
end
end
--
1.8.0.2
[PATCH core 4/8] Remove index creation errors when database is already created
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/db.rb | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/server/lib/db.rb b/server/lib/db.rb
index 64cc283..49e6f33 100644
--- a/server/lib/db.rb
+++ b/server/lib/db.rb
@@ -16,22 +16,29 @@ module Deltacloud
end
def self.initialize_database
+ db = database
- database.create_table?(:providers) {
+ db.create_table?(:providers) {
primary_key :id
column :driver, :string, { :null => false }
column :url, :string
- index [ :url, :driver ]
+ index [ :url, :driver ] if !db.table_exists?(:providers)
}
- database.create_table?(:entities) {
+ db.create_table?(:entities) {
primary_key :id
- foreign_key :provider_id, :providers, { :index => true, :null => false }
+
+ unless db.table_exists?(:entities)
+ foreign_key :provider_id, :providers, { :index => true, :null => false }
+ end
+
column :created_at, :timestamp
# Base
- column :model, :string, { :index => true, :null => false, :default => 'entity' }
+ unless db.table_exists?(:entities)
+ column :model, :string, { :index => true, :null => false, :default => 'entity' }
+ end
# Map Entity to Deltacloud model
# (like: Machine => Instance)
--
1.8.0.2
[PATCH core 8/8] Initial database tests for CIMI frontend
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/Rakefile | 1 +
server/tests/cimi/db/database_helper_test.rb | 190 +++++++++++++++++++++++++++
server/tests/cimi/db/db_helper.rb | 22 ++++
server/tests/cimi/db/schema_test.rb | 94 +++++++++++++
4 files changed, 307 insertions(+)
create mode 100644 server/tests/cimi/db/database_helper_test.rb
create mode 100644 server/tests/cimi/db/db_helper.rb
create mode 100644 server/tests/cimi/db/schema_test.rb
diff --git a/server/Rakefile b/server/Rakefile
index cc17034..b8b3ea1 100644
--- a/server/Rakefile
+++ b/server/Rakefile
@@ -206,6 +206,7 @@ namespace :test do
t.loader = :testrb
end
t.test_files = FileList[
+ 'tests/cimi/db/*test.rb', # CIMI frontend database tests
'tests/cimi/model/*spec.rb', # CIMI frontend serialization API tests
'tests/cimi/collections/*test.rb', # CIMI frontend API tests
]
diff --git a/server/tests/cimi/db/database_helper_test.rb b/server/tests/cimi/db/database_helper_test.rb
new file mode 100644
index 0000000..7bd3e23
--- /dev/null
+++ b/server/tests/cimi/db/database_helper_test.rb
@@ -0,0 +1,190 @@
+require 'rubygems'
+require 'require_relative' if RUBY_VERSION < '1.9'
+require 'minitest/autorun'
+
+require_relative 'db_helper.rb'
+require_relative '../spec_helper.rb'
+require_relative './../collections/common.rb'
+
+class DatabaseHelper
+ include Deltacloud::Helpers::Database
+end
+
+describe Deltacloud::Helpers::Database do
+ include Deltacloud::DatabaseTestHelper
+
+ before do
+ ENV['RACK_ENV'] = 'development'
+ @db = DatabaseHelper.new
+ end
+
+ it 'report if application is running under test environment' do
+ ENV['RACK_ENV'] = 'test'
+ @db.test_environment?.must_equal true
+ ENV['RACK_ENV'] = 'development'
+ @db.test_environment?.must_equal false
+ end
+
+ it 'report if given entity is provided by database' do
+ @db.provides?('machine_template').must_equal true
+ @db.provides?('machine').must_equal false
+ end
+
+ it 'reports the current provider' do
+ @db.current_provider.must_equal 'default'
+ end
+
+ it 'create provider when it does not exists' do
+ @db.current_db.must_be_kind_of Deltacloud::Database::Provider
+ @db.current_db.driver.must_equal 'mock'
+ @db.current_db.url.must_equal @db.current_provider
+ @db.current_db.must_respond_to :entities
+ @db.current_db.must_respond_to :machine_templates
+ @db.current_db.must_respond_to :address_templates
+ @db.current_db.must_respond_to :volume_configurations
+ @db.current_db.must_respond_to :volume_templates
+ end
+
+ it 'extract attributes both from JSON and XMLSimple' do
+ xml_simple_test = { 'property' => [ { 'key' => 'template', 'content' => "value"} ] }
+ json_test = { 'properties' => { 'template' => 'value' } }
+
+ @db.extract_attribute_value('property', xml_simple_test).must_equal('template' => 'value')
+ @db.extract_attribute_value('properties', json_test).must_equal('template' => 'value')
+ end
+
+ it 'must return entity for given model' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ @db.current_db.wont_be_nil
+
+ new_entity = @db.current_db.add_entity(
+ :name => 'testMachine1',
+ :description => 'testMachine1 description',
+ :ent_properties => JSON::dump(:key => 'value'),
+ :be_kind => 'instance',
+ :be_id => 'inst1'
+ )
+
+ check_entity_base_attrs new_entity, entity, @db.current_db
+
+ result = @db.get_entity(Instance.new(:id => 'inst1'))
+ result.must_equal new_entity
+
+ new_entity.destroy.wont_equal false
+ end
+
+ it 'must load attributes for entity for given model' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ @db.current_db.wont_be_nil
+
+ new_entity = @db.current_db.add_entity(
+ :name => 'testMachine1',
+ :description => 'testMachine1 description',
+ :ent_properties => JSON::dump(:key => 'value'),
+ :be_kind => 'instance',
+ :be_id => 'inst1'
+ )
+
+ check_entity_base_attrs new_entity, entity, @db.current_db
+
+ result = @db.load_attributes_for(Instance.new(:id => 'inst1'))
+ result.must_be_kind_of Hash
+ result[:name].must_equal new_entity.name
+ result[:description].must_equal new_entity.description
+ result[:property].must_equal JSON::parse(new_entity.ent_properties)
+
+ new_entity.destroy.wont_equal false
+ end
+
+ it 'must delete attributes for entity for given model' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ @db.current_db.wont_be_nil
+
+ new_entity = @db.current_db.add_entity(
+ :name => 'testMachine1',
+ :description => 'testMachine1 description',
+ :ent_properties => JSON::dump(:key => 'value'),
+ :be_kind => 'instance',
+ :be_id => 'inst1'
+ )
+
+ check_entity_base_attrs new_entity, entity, @db.current_db
+
+ result = @db.delete_attributes_for(Instance.new(:id => 'inst1'))
+ result.wont_equal false
+ result.exists?.must_equal false
+ end
+
+ it 'must store JSON attributes for entity for given model' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ @db.current_db.wont_be_nil
+
+ mock_instance = Instance.new(:id => 'inst1')
+ mock_json = '
+{
+ "resourceURI": "http://schemas.dmtf.org/cimi/1/MachineCreate",
+ "name": "myDatabaseMachine",
+ "description": "This is a demo machine",
+ "properties": {
+ "foo": "bar",
+ "life": "is life"
+ },
+ "machineTemplate": {
+ "machineConfig": { "href": "http://localhost:3001/cimi/machine_configurations/m1-small" },
+ "machineImage": { "href": "http://localhost:3001/cimi/machine_images/img1" }
+ }
+}
+ '
+ result = @db.store_attributes_for(mock_instance, JSON::parse(mock_json))
+ result.must_be_kind_of entity
+ check_entity_base_attrs result, entity, @db.current_db
+ load_result = @db.load_attributes_for(mock_instance)
+ load_result.must_be_kind_of Hash
+ load_result.wont_be_empty
+ load_result[:name].must_equal 'myDatabaseMachine'
+ load_result[:description].must_equal 'This is a demo machine'
+ load_result[:property].must_be_kind_of Hash
+ load_result[:property].wont_be_empty
+ load_result[:property]['foo'].must_equal 'bar'
+ load_result[:property]['life'].must_equal 'is life'
+ result.destroy.wont_equal false
+ end
+
+ it 'must store XML attributes for entity for given model' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ @db.current_db.wont_be_nil
+
+ mock_instance = Instance.new(:id => 'inst1')
+ mock_xml = '
+<MachineCreate>
+ <name>myMachineXML123</name>
+ <description>Description of my new Machine</description>
+ <machineTemplate>
+ <machineConfig href="http://localhost:3001/cimi/machine_configurations/m1-small"/>
+ <machineImage href="http://localhost:3001/cimi/machine_images/img1"/>
+ </machineTemplate>
+ <property key="test">value</property>
+ <property key="foo">bar</property>
+</MachineCreate>
+ '
+ result = @db.store_attributes_for(mock_instance, XmlSimple.xml_in(mock_xml))
+ result.must_be_kind_of entity
+ check_entity_base_attrs result, entity, @db.current_db
+ load_result = @db.load_attributes_for(mock_instance)
+ load_result.must_be_kind_of Hash
+ load_result.wont_be_empty
+ load_result[:name].must_equal 'myMachineXML123'
+ load_result[:description].must_equal 'Description of my new Machine'
+ load_result[:property].must_be_kind_of Hash
+ load_result[:property].wont_be_empty
+ load_result[:property]['test'].must_equal 'value'
+ result.destroy.wont_equal false
+ end
+
+
+end
diff --git a/server/tests/cimi/db/db_helper.rb b/server/tests/cimi/db/db_helper.rb
new file mode 100644
index 0000000..9bbdf30
--- /dev/null
+++ b/server/tests/cimi/db/db_helper.rb
@@ -0,0 +1,22 @@
+# Memory database
+ENV['DATABASE_LOCATION'] = 'sqlite:/'
+
+module Deltacloud
+ module DatabaseTestHelper
+
+ def check_entity_base_attrs(entity, entity_klass, provider)
+ entity.must_be_kind_of entity_klass
+ entity.id.wont_be_nil
+ entity.created_at.wont_be_nil
+ entity.name.wont_be_empty
+ entity.description.wont_be_empty
+ entity.provider.must_equal provider
+ entity.model.must_equal entity_klass
+ entity.to_hash[:name].must_equal entity.name
+ entity.to_hash[:description].must_equal entity.description
+ entity.to_hash[:property].must_be_kind_of Hash
+ entity.to_hash[:property].wont_be_empty
+ end
+
+ end
+end
diff --git a/server/tests/cimi/db/schema_test.rb b/server/tests/cimi/db/schema_test.rb
new file mode 100644
index 0000000..db5e71c
--- /dev/null
+++ b/server/tests/cimi/db/schema_test.rb
@@ -0,0 +1,94 @@
+require 'rubygems'
+require 'require_relative' if RUBY_VERSION < '1.9'
+
+require_relative 'db_helper.rb'
+require_relative '../spec_helper.rb'
+
+describe Deltacloud::Database do
+
+ include Deltacloud::DatabaseTestHelper
+
+ before do
+ @db = Deltacloud.database
+ end
+
+ it 'has valid database connection' do
+ @db.test_connection.must_equal true
+ end
+
+ it 'creates the database schema' do
+ @db.tables.wont_be_empty
+ @db.tables.must_include :providers
+ @db.tables.must_include :entities
+ end
+
+ it 'should allow creation of providers' do
+ provider = Deltacloud::Database::Provider
+ provider.table_name.must_equal :providers
+ new_provider = provider.create(:driver => 'mock', :url => 'test1')
+ new_provider.must_be_kind_of provider
+ new_provider.destroy.wont_equal false
+ end
+
+ it 'should not allow creation of provider with nil driver' do
+ provider = Deltacloud::Database::Provider
+ lambda {
+ new_provider = provider.create(:driver => nil, :url => 'test1')
+ }.must_raise Sequel::InvalidValue
+ end
+
+ it 'allow creation of simple entity' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::Entity
+ entity.table_name.must_equal :entities
+
+ entity_provider = provider.create(:driver => :mock)
+
+ new_entity = entity_provider.add_entity(
+ :name => 'testEntity1',
+ :description => 'testEntity1 description',
+ :ent_properties => JSON::dump(:key => 'value')
+ )
+
+ check_entity_base_attrs new_entity, entity, entity_provider
+
+ new_entity.destroy.wont_equal false
+ entity_provider.destroy.wont_equal false
+ end
+
+ it 'allow creation of extended entities' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::MachineTemplate
+ entity.table_name.must_equal :entities
+ entity_provider = provider.create(:driver => :mock)
+ new_entity = entity_provider.add_machine_template(
+ :name => 'testMachineTemplate1',
+ :description => 'testMachineTemplate1 description',
+ :ent_properties => JSON::dump(:key => 'value'),
+ :machine_config => 'http://example.com/cimi/machine_configurations/m1-small',
+ :machine_image => 'http://example.com/cimi/machine_image/img1'
+ )
+ check_entity_base_attrs new_entity, entity, entity_provider
+
+ new_entity.machine_config.wont_be_empty
+ new_entity.machine_image.wont_be_empty
+
+ new_entity.destroy.wont_equal false
+ entity_provider.destroy.wont_equal false
+ end
+
+ it 'validate presence of required attributes for extended entities' do
+ provider = Deltacloud::Database::Provider
+ entity = Deltacloud::Database::MachineTemplate
+ entity.table_name.must_equal :entities
+ entity_provider = provider.create(:driver => :mock)
+ lambda {
+ new_entity = entity_provider.add_machine_template(
+ :name => 'testMachineTemplate1',
+ :description => 'testMachineTemplate1 description',
+ :ent_properties => JSON::dump(:key => 'value'),
+ )
+ }.must_raise Sequel::ValidationFailed
+ end
+
+end
--
1.8.0.2
[PATCH core 6/8] Fixed bugs in storing entity data to database
Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>
Signed-off-by: Michal fojtik <mf...@redhat.com>
---
server/lib/cimi/helpers/database_helper.rb | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/server/lib/cimi/helpers/database_helper.rb b/server/lib/cimi/helpers/database_helper.rb
index d432f69..e6f73fe 100644
--- a/server/lib/cimi/helpers/database_helper.rb
+++ b/server/lib/cimi/helpers/database_helper.rb
@@ -54,7 +54,11 @@ module Deltacloud
return if model.id.nil?
unless entity = get_entity(model)
- entity = Deltacloud::Database::Entity.new(:provider_id => current_db.id)
+ entity = Deltacloud::Database::Entity.new(
+ :provider_id => current_db.id,
+ :be_id => model.id,
+ :be_kind => model.to_entity
+ )
end
entity.description = extract_attribute_value('description', attrs) if attrs.has_key? 'description'
@@ -76,7 +80,13 @@ module Deltacloud
#
def extract_attribute_value(name, attrs={})
return unless attrs[name]
- attrs[name].is_a?(Array) ? attrs[name].first : attrs[name]
+ if name == 'property'
+ attrs[name].is_a?(Array) ?
+ attrs[name].inject({}) { |r, v| r[v['key']] = v['content']; r} :
+ attrs[name]
+ else
+ attrs[name].is_a?(Array) ? attrs[name].first : attrs[name]
+ end
end
end
--
1.8.0.2