Class: Visor::Meta::Backends::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/meta/backends/base.rb

Overview

This is the Base super class for all Backends. Each new backend inherits from Base, which contains the model and all validations for the images metadata.

Implementing a new backend is as simple as create a new backend class which inherits from Base and them implement the specific methods for querying the underlying database.

Direct Known Subclasses

MongoDB, MySQL

Constant Summary collapse

MANDATORY =

Keys validation

Mandatory attributes

[:name, :architecture]
READONLY =

Read-only attributes

[:_id, :uri, :created_at, :updated_at, :accessed_at, :access_count]
OPTIONAL =

Optional attributes

[:owner, :status, :size, :checksum, :access, :type, :format,
:uploaded_at, :store, :location, :kernel, :ramdisk]
ALL =

All attributes

MANDATORY + OPTIONAL + READONLY
ARCHITECTURE =

Values validation

Architecture options

%w[i386 x86_64]
ACCESS =

Access options

%w[public private]
FORMAT =

Possible disk formats

%w[iso vhd vdi vmdk ovf ami aki ari]
TYPE =

Possible types

%w[kernel ramdisk machine]
STATUS =

Possible status

%w[locked uploading error available]
STORE =

Possible storage

%w[s3 cumulus walrus hdfs lcs http file]
BRIEF =

Presentation options

Brief attributes used to return only brief information about images.

[:_id, :name, :architecture, :type, :format, :store, :size]
DETAIL_EXC =

Attributes to exclude from get public images requests, allowing to show other custom attributes.

[:accessed_at, :access_count]
FILTERS =

Valid parameters to filter results from requests query, add sort parameter and sort direction.

ALL + [:sort, :dir]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Base

Initializes a Backend instance.

Parameters:

  • [Hash] (Hash)

    a customizable set of options

  • opts (Hash)

    a customizable set of options

Options Hash (opts):

  • :host (String)

    The host address.

  • :port (Integer)

    The port to be used.

  • :db (String)

    The wanted database.

  • :user (String)

    The username to be authenticate db access.

  • :password (String)

    The password to be authenticate db access.

  • :conn (Object)

    The connection pool to access database.



62
63
64
65
66
67
68
69
# File 'lib/meta/backends/base.rb', line 62

def initialize(opts)
  @host     = opts[:host]
  @port     = opts[:port]
  @db       = opts[:db]
  @user     = opts[:user]
  @password = opts[:password]
  @conn     = opts[:conn]
end

Instance Attribute Details

#connObject (readonly)

Returns the value of attribute conn.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def conn
  @conn
end

#dbObject (readonly)

Returns the value of attribute db.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def db
  @db
end

#hostObject (readonly)

Returns the value of attribute host.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def host
  @host
end

#passwordObject (readonly)

Returns the value of attribute password.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def password
  @password
end

#portObject (readonly)

Returns the value of attribute port.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def port
  @port
end

#userObject (readonly)

Returns the value of attribute user.



49
50
51
# File 'lib/meta/backends/base.rb', line 49

def user
  @user
end

Instance Method Details

#build_uri(id) ⇒ String

Build an URI for the given image _id based on VISoR Image Server configuration.

Parameters:

  • id (String)

    The _id of the image.

Returns:

  • (String)

    The generated URI.



161
162
163
164
165
166
# File 'lib/meta/backends/base.rb', line 161

def build_uri(id)
  conf = Visor::Common::Config.load_config :visor_image
  host = conf[:bind_host] || Visor::Meta::Server::DEFAULT_HOST
  port = conf[:bind_port] || Visor::Meta::Server::DEFAULT_PORT
  "http://#{host}:#{port}/images/#{id}"
end

#deserialize_others(meta) ⇒ Object

Deserializes with JSON and decapsulate additional (not on the table schema) image attributes from the others schema field.

This is used for SQL Backends, as they are not schema free.

Examples:

Instantiate a client with default values:

# So this:
{name: "example", access: "public", others: "{\"extra_key\":\"value\",\"another\":\"value\"}"}"}
# becomes this:
{name: 'example', access: 'public', extra_key: 'value', another: 'value'}

Parameters:

  • meta (Hash)

    The image metadata.



203
204
205
206
207
208
# File 'lib/meta/backends/base.rb', line 203

def deserialize_others(meta)
  if meta[:others]
    others = meta.delete :others
    meta.merge! JSON.parse(others, symbolize_names: true)
  end
end

#serialize_others(meta) ⇒ Object

Serializes with JSON and encapsulate additional (not on the table schema) image attributes on the others schema field.

This is used for SQL Backends, as they are not schema free.

Examples:

Instantiate a client with default values:

# So this:
{name: 'example', access: 'public', extra_key: 'value', another: 'value'}
# becomes this:
{name: "example", access: "public", others: "{\"extra_key\":\"value\",\"another\":\"value\"}"}"}

Parameters:

  • meta (Hash)

    The image metadata.



181
182
183
184
185
186
187
188
# File 'lib/meta/backends/base.rb', line 181

def serialize_others(meta)
  other_keys = meta.keys - ALL
  unless other_keys.empty?
    others = {}
    other_keys.each { |key| others[key] = meta.delete(key) }
    meta.merge!(others: others.to_json)
  end
end

#set_protected_post(meta, opts = {}) ⇒ Hash

Set protected fields value from a post operation. Being them the _id, uri, owner, size, access, status and created_at.

Parameters:

  • meta (Hash)

    The image metadata.

  • [Hash] (Hash)

    a customizable set of options

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :owner (String) — default: Nil

    The image owner.

  • :size (String) — default: Nil

    The image file size.

Returns:

  • (Hash)

    The image metadata filled with protected fields values.



135
136
137
138
139
140
141
142
# File 'lib/meta/backends/base.rb', line 135

def set_protected_post(meta, opts = {})
  owner, size = opts[:owner], opts[:size]
  meta.merge!(_id: SecureRandom.uuid)
  meta.merge!(access: 'public') unless meta[:access]
  meta.merge!(owner: owner) if owner
  meta.merge!(size: size) if size
  meta.merge!(created_at: Time.now, uri: build_uri(meta[:_id]), status: 'locked')
end

#set_protected_put(meta) ⇒ Hash

Set protected fields value from a get operation. Being them the accessed_at and access_count.

Parameters:

  • meta (Hash)

    The image metadata update.

Returns:

  • (Hash)

    The image metadata update with protected fields setted.



151
152
153
# File 'lib/meta/backends/base.rb', line 151

def set_protected_put(meta)
  meta.merge!(updated_at: Time.now)
end

#string_time_or_hash?(v) ⇒ true, false

Verifies if a given object is a String, a Time or a Hash.

Parameters:

  • v (Object)

    The input value.

Returns:

  • (true, false)

    If the provided value is or not a String, a Time or a Hash.



216
217
218
# File 'lib/meta/backends/base.rb', line 216

def string_time_or_hash?(v)
  v.is_a?(String) or v.is_a?(Time) or v.is_a?(Hash)
end

#to_sql_insert(h) ⇒ String

Generates a compatible SQL INSERT string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “(k, k1) VALUES (‘v’, ‘v1’)”, only Strings Times or Hashes values are surrounded with ‘<value>’.



249
250
251
252
# File 'lib/meta/backends/base.rb', line 249

def to_sql_insert(h)
  surround = h.values.map { |v| string_time_or_hash?(v) ? "'#{v}'" : v }
  %W{(#{h.keys.join(', ')}) (#{surround.join(', ')})}
end

#to_sql_update(h) ⇒ String

Generates a compatible SQL UPDATE string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “k=‘v’, k1=‘v1’”, only Strings Times or Hashes values are surrounded with ‘<value>’.



238
239
240
# File 'lib/meta/backends/base.rb', line 238

def to_sql_update(h)
  h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(', ')
end

#to_sql_where(h) ⇒ String

Generates a compatible SQL WHERE string from a hash.

Parameters:

  • h (Hash)

    The input hash.

Returns:

  • (String)

    A string as “k=‘v’ AND k1=‘v1’”, only Strings Times or Hashes values are surrounded with ‘<value>’.



227
228
229
# File 'lib/meta/backends/base.rb', line 227

def to_sql_where(h)
  h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(' AND ')
end

#validate_data_post(meta) ⇒ Object

Validates the image metadata for a post operation, based on possible keys and values.

@raise If some of the metadata fields do not respect the

possible values, contains any read-only or misses any mandatory field.

Parameters:

  • meta (Hash)

    The image metadata.



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/meta/backends/base.rb', line 78

def validate_data_post(meta)
  meta.assert_exclusion_keys(READONLY)
  meta.assert_inclusion_keys(MANDATORY)

  meta.assert_valid_values_for(:architecture, ARCHITECTURE)
  meta.assert_valid_values_for(:access, ACCESS)
  meta.assert_valid_values_for(:format, FORMAT)
  meta.assert_valid_values_for(:type, TYPE)
  meta.assert_valid_values_for(:store, STORE)

  assert_ramdisk_and_kernel(meta)
end

#validate_data_put(meta) ⇒ Object

Validates the image metadata for a put operation, based on possible keys and values.

@raise If some of the metadata fields do not respect the

possible values, contains any read-only or misses any mandatory field.

Parameters:

  • meta (Hash)

    The image metadata.



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/meta/backends/base.rb', line 98

def validate_data_put(meta)
  meta.assert_exclusion_keys(READONLY)

  meta.assert_valid_values_for(:architecture, ARCHITECTURE)
  meta.assert_valid_values_for(:access, ACCESS)
  meta.assert_valid_values_for(:format, FORMAT)
  meta.assert_valid_values_for(:type, TYPE)
  meta.assert_valid_values_for(:store, STORE)

  assert_ramdisk_and_kernel(meta)
end

#validate_query_filters(filters) ⇒ Object

Validates that incoming query filters fields are valid.

@raise If some of the query filter fields do not respect the

possible values.

Parameters:

  • filters (Hash)

    The image metadata filters comming from a GET request.



117
118
119
120
121
# File 'lib/meta/backends/base.rb', line 117

def validate_query_filters(filters)
  filters.symbolize_keys!
  filters.assert_valid_keys(FILTERS)

end