Skip to content

Commit

Permalink
Merge pull request #13845 from abellotti/api_collection_class
Browse files Browse the repository at this point in the history
Api enhancement to support optional collection_class parameter
  • Loading branch information
Fryguy authored Feb 10, 2017
2 parents 83fc4e2 + dd8fd54 commit 242d104
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
43 changes: 32 additions & 11 deletions app/controllers/api/base_controller/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,9 @@ def validate_api_request
end

def validate_optional_collection_classes
@collection_klasses = {} # Default all to config classes
param = params['provider_class']
return unless param.present?

raise BadRequestError, "Unsupported provider_class #{param} specified" if param != "provider"
%w(tags policies policy_profiles).each do |cname|
if @req.subcollection == cname || @req.expand?(cname)
raise BadRequestError, "Management of #{cname} is unsupported for the Provider class"
end
end
@collection_klasses[:providers] = Provider
@collection_klasses = {} # Default all to config classes
validate_provider_class
validate_collection_class
end

def validate_api_action
Expand Down Expand Up @@ -331,6 +323,35 @@ def assert_all_required_fields_exists(data, type, required_fields)
raise BadRequestError, "Resource #{missing_fields.join(", ")} needs be specified for creating a new #{type}"
end
end

def validate_provider_class
param = params['provider_class']
return unless param.present?

raise BadRequestError, "Unsupported provider_class #{param} specified" if param != "provider"
%w(tags policies policy_profiles).each do |cname|
if @req.subcollection == cname || @req.expand?(cname)
raise BadRequestError, "Management of #{cname} is unsupported for the Provider class"
end
end
@collection_klasses[:providers] = Provider
end

def validate_collection_class
param = params['collection_class']
return unless param.present?

klass = collection_class(@req.collection)
return if param == klass.name

param_klass = klass.descendants.detect { |sub_klass| param == sub_klass.name }
if param_klass.present?
@collection_klasses[@req.collection.to_sym] = param_klass
return
end

raise BadRequestError, "Invalid collection_class #{param} specified for the #{@req.collection} collection"
end
end
end
end
40 changes: 40 additions & 0 deletions spec/requests/api/querying_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -706,4 +706,44 @@ def create_vms_by_name(names)
expect(response.headers['Access-Control-Allow-Methods']).to include('OPTIONS')
end
end

describe "with optional collection_class" do
before { api_basic_authorize collection_action_identifier(:vms, :read, :get) }

it "fail with invalid collection_class specified" do
run_get vms_url, :collection_class => "BogusClass"

expect_bad_request("Invalid collection_class BogusClass specified for the vms collection")
end

it "succeed with collection_class matching the collection class" do
create_vms_by_name(%w(aa bb))

run_get vms_url, :collection_class => "Vm"

expect_query_result(:vms, 2, 2)
end

it "succeed with collection_class matching the collection class and returns subclassed resources" do
FactoryGirl.create(:vm_vmware, :name => "aa")
FactoryGirl.create(:vm_vmware_cloud, :name => "bb")
FactoryGirl.create(:vm_vmware_cloud, :name => "cc")

run_get vms_url, :expand => "resources", :collection_class => "Vm"

expect_query_result(:vms, 3, 3)
expect(response.parsed_body["resources"].collect { |vm| vm["name"] }).to match_array(%w(aa bb cc))
end

it "succeed with collection_class and only returns subclassed resources" do
FactoryGirl.create(:vm_vmware, :name => "aa")
FactoryGirl.create(:vm_vmware_cloud, :name => "bb")
vmcc = FactoryGirl.create(:vm_vmware_cloud, :name => "cc")

run_get vms_url, :expand => "resources", :collection_class => vmcc.class.name

expect_query_result(:vms, 2, 2)
expect(response.parsed_body["resources"].collect { |vm| vm["name"] }).to match_array(%w(bb cc))
end
end
end
2 changes: 1 addition & 1 deletion tools/rest_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class Cli
API_PARAMETERS = %w(expand hide attributes decorators limit offset
depth search_options
sort_by sort_order sort_options
filter by_tag provider_class requester_type).freeze
filter by_tag provider_class collection_class requester_type).freeze

MULTI_PARAMS = %w(filter).freeze

Expand Down

0 comments on commit 242d104

Please sign in to comment.