1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Solid query API mixin, with tests

Preloads :id, and :name if available. Leaves everything else up to lazy-loading, though optionally can call a per-collection function to add more values if available
This commit is contained in:
Mike Pountney 2014-06-18 00:48:08 +01:00
parent b43d48928a
commit 65a10cae67
5 changed files with 62 additions and 26 deletions

View file

@ -5,10 +5,17 @@ module Fog
module Compute
class VcloudDirector
class Networks < Collection
include Fog::VcloudDirector::Query
model Fog::Compute::VcloudDirector::Network
attribute :organization
def query_type
"orgVdcNetwork"
end
private
def get_by_id(item_id)

View file

@ -12,6 +12,10 @@ module Fog
attribute :vdc
def query_type
"vApp"
end
private
def get_by_id(item_id)

View file

@ -1,53 +1,49 @@
require 'pp'
module Fog
module VcloudDirector
module Query
def find_by_query(type, options)
def find_by_query(options={})
type = options.fetch(:type) { self.query_type }
results = get_all_results(type, options)
results.map do |result|
{ :id => result[:href].split('/').last }
data = results.map do |query_record|
model_data = {}
model_data[:id] = query_record[:href].split('/').last
model_data[:name] = query_record.fetch(:name) if query_record.key?(:name)
if self.methods.include?(:populate_model_from_query_record)
model_data.merge(self.populate_model_from_query_record(query_record))
else
model_data
end
end
load(data)
end
private
def get_entity_types_in_record_format(query_body)
query_links = query_body.fetch(:Link).select do |link|
link[:rel] == 'down'
end
entity_types = []
query_links.each do |link|
(entity_type, query_format) = extract_query_type_and_format_from_link(link)
entity_types << entity_type if query_format == 'records'
end
entity_types
end
def extract_query_type_and_format_from_link(link)
href = Nokogiri::XML.fragment(link[:href])
query = CGI.parse(URI.parse(href.text).query)
query_format = query['format'].first
query_type = query['type'].first
[query_type, query_format]
end
def get_all_results(type, options)
results = []
(1..get_num_pages(type, options)).each do |page|
if options.key?(:page)
page_range = [ Integer(options[:page]) ]
else
page_range = (1..get_num_pages(type, options))
end
page_range.each do |page|
results += get_results_page(page, type, options) || []
end
results
end
def get_num_pages(type, options)
body = @fsi.get_execute_query(type, options)
body = service.get_execute_query(type, options)
last_page = body[:lastPage] || 1
raise "Invalid lastPage (#{last_page}) in query results" unless last_page.is_a? Integer
last_page.to_i
end
def get_results_page(page, type, options)
body = @fsi.get_execute_query(type, options.merge({:page=>page}))
body = service.get_execute_query(type, options.merge({:page=>page})).body
record_key = key_of_first_record_or_reference(body)
body[record_key] = [body[record_key]] if body[record_key].is_a?(Hash)

View file

@ -72,6 +72,7 @@ Shindo.tests("Compute::VcloudDirector | networks", ['vclouddirector', 'all']) do
tests("#get").returns(network.id) { networks.get(network.id).id }
end
# Now let's also check against an isolated network, since these have some
# additional features like DHCP ServiceConfigurations.
isolated_network_raw = nil
@ -88,4 +89,20 @@ Shindo.tests("Compute::VcloudDirector | networks", ['vclouddirector', 'all']) do
tests("#fence_mode is now loaded").returns(true) { isolated_network.attributes[:fence_mode] != NonLoaded }
end
# We should also be able to find these same networks via Query API
tests("Compute::VcloudDirector | networks", ['find_by_query']) do
tests('we can retrieve :name without lazy loading').returns(network.name) do
query_network = networks.find_by_query(:filter => "name==#{network.name}").first
query_network.attributes[:name]
end
tests('by name: natRouted').returns(network.name) do
query_network = networks.find_by_query(:filter => "name==#{network.name}").first
query_network.name
end
tests('by name: isolated').returns(isolated_network.name) do
query_network = networks.find_by_query(:filter => "name==#{isolated_network.name}").first
query_network.name
end
end
end

View file

@ -46,4 +46,16 @@ Shindo.tests("Compute::VcloudDirector | vapps", ['vclouddirector', 'all']) do
tests("#delete_custom_field").returns([]){ vapp.custom_fields.delete(:custom_field); vapp.custom_fields }
end
# We should also be able to find this vApp via Query API
tests("Compute::VcloudDirector | vapps", ['find_by_query']) do
tests('we can retrieve :name without lazy loading').returns(vapp.name) do
query_vapp = vapps.find_by_query(:filter => "name==#{vapp.name}").first
query_vapp.attributes[:name]
end
tests('we can retrieve name via model object returned by query').returns(vapp.name) do
query_vapp = vapps.find_by_query(:filter => "name==#{vapp.name}").first
query_vapp.name
end
end
end