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:
parent
b43d48928a
commit
65a10cae67
5 changed files with 62 additions and 26 deletions
|
@ -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)
|
||||
|
|
|
@ -12,6 +12,10 @@ module Fog
|
|||
|
||||
attribute :vdc
|
||||
|
||||
def query_type
|
||||
"vApp"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_by_id(item_id)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue