Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit 035915d

Browse files
Get guid,name of service broker in service offering list request
[#172379562](https://www.pivotaltracker.com/story/show/172379562)
1 parent 8fd59c2 commit 035915d

8 files changed

Lines changed: 141 additions & 3 deletions

File tree

app/controllers/v3/service_offerings_controller.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require 'actions/service_offering_delete'
99
require 'actions/transactional_metadata_update'
1010
require 'controllers/v3/mixins/service_permissions'
11+
require 'decorators/field_service_offering_service_broker_decorator'
1112

1213
class ServiceOfferingsController < ApplicationController
1314
include ServicePermissions
@@ -30,11 +31,15 @@ def index
3031
)
3132
end
3233

34+
decorators = []
35+
decorators << FieldServiceOfferingServiceBrokerDecorator.new(message.fields) if FieldServiceOfferingServiceBrokerDecorator.match?(message.fields)
36+
3337
presenter = Presenters::V3::PaginatedListPresenter.new(
3438
presenter: Presenters::V3::ServiceOfferingPresenter,
3539
paginated_result: SequelPaginator.new.get_page(dataset, message.try(:pagination_options)),
3640
message: message,
3741
path: '/v3/service_offerings',
42+
decorators: decorators
3843
)
3944

4045
render status: :ok, json: presenter.to_json
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module VCAP::CloudController
2+
class FieldServiceOfferingServiceBrokerDecorator
3+
def self.allowed
4+
Set['name', 'guid']
5+
end
6+
7+
def self.match?(fields)
8+
fields.is_a?(Hash) && fields[:'service_broker']&.to_set&.intersect?(self.allowed)
9+
end
10+
11+
def initialize(fields)
12+
@fields = fields[:'service_broker'].to_set.intersection(self.class.allowed)
13+
end
14+
15+
def decorate(hash, service_offerings)
16+
hash[:included] ||= {}
17+
service_brokers = service_offerings.map(&:service_broker).uniq
18+
hash[:included][:service_brokers] = service_brokers.sort_by(&:created_at).map do |broker|
19+
broker_view = {}
20+
broker_view[:name] = broker.name if @fields.include?('name')
21+
broker_view[:guid] = broker.guid if @fields.include?('guid')
22+
broker_view
23+
end
24+
25+
hash
26+
end
27+
end
28+
end

app/messages/service_offerings_list_message.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,32 @@
33

44
module VCAP::CloudController
55
class ServiceOfferingsListMessage < MetadataListMessage
6-
register_allowed_keys [
7-
:available,
6+
@array_keys = [
87
:service_broker_guids,
98
:service_broker_names,
109
:names,
1110
:space_guids,
1211
:organization_guids,
1312
]
1413

14+
@single_keys = [
15+
:available,
16+
:fields
17+
]
18+
19+
register_allowed_keys(@single_keys + @array_keys)
20+
1521
validates_with NoAdditionalParamsValidator
1622
validates :available, inclusion: { in: %w(true false), message: "only accepts values 'true' or 'false'" }, allow_nil: true
1723

24+
validates :fields, allow_nil: true, fields: {
25+
allowed: {
26+
'service_broker' => ['guid', 'name']
27+
}
28+
}
29+
1830
def self.from_params(params)
19-
super(params, %w(service_broker_guids service_broker_names names space_guids organization_guids))
31+
super(params, @array_keys.map(&:to_s), fields: %w(fields))
2032
end
2133
end
2234
end

docs/v3/source/includes/experimental_resources/service_offerings/_list.md.erb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ Name | Type | Description
3737
**space_guids** | _list of strings_ | Comma-delimited list of Space GUIDs to filter by.
3838
**organization_guids** | _list of strings_ | Comma-delimited list of Organization GUIDs to filter by.
3939
**label_selector** | _string_ | **Experimental** - A query string containing a list of [label selector](#labels-and-selectors) requirements.
40+
**fields** | [_fields parameter_](#fields-parameter) | **Experimental** [_Allowed values_](#service-offerings-list-fields)
41+
42+
##### Service Offerings List Fields
43+
44+
Resource | Allowed Keys
45+
------------------- | ----
46+
service_broker| `guid`, `name`
4047

4148
#### Permitted roles
4249
|

spec/field_message_spec_shared_examples.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,18 @@
2525
quoted_keys = keys_list.map { |k| "'#{k}'" }
2626
expect(message.errors[:fields]).to include("valid keys for '#{resource}' are: #{quoted_keys.join(', ')}")
2727
end
28+
29+
it 'validates `fields` is a hash' do
30+
message = described_class.from_params({ 'fields' => 'foo' }.with_indifferent_access)
31+
expect(message).not_to be_valid
32+
expect(message.errors[:fields][0]).to include('must be an object')
33+
end
34+
35+
it 'does not accept fields resources that are not allowed' do
36+
message = described_class.from_params({ 'fields' => { 'space.foo': 'name' } })
37+
expect(message).not_to be_valid
38+
expect(message.errors[:fields]).to include(include(
39+
'[space.foo] valid resources are:'
40+
))
41+
end
2842
end

spec/request/service_offerings_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@
204204
page: 2,
205205
order_by: 'updated_at',
206206
label_selector: 'foo==bar',
207+
fields: { 'service_broker' => 'name' }
207208
}
208209
end
209210
end
@@ -690,6 +691,22 @@
690691
it_behaves_like 'permissions for list endpoint', COMPLETE_PERMISSIONS
691692
end
692693
end
694+
695+
describe 'fields' do
696+
let!(:service_1) { VCAP::CloudController::Service.make }
697+
let!(:service_2) { VCAP::CloudController::Service.make }
698+
699+
it 'can include service broker name and guid' do
700+
get '/v3/service_offerings?fields[service_broker]=name,guid', nil, admin_headers
701+
expect(last_response).to have_status_code(200)
702+
703+
expect(parsed_response['included']['service_brokers']).to have(2).elements
704+
expect(parsed_response['included']['service_brokers'][0]['guid']).to eq(service_1.service_broker.guid)
705+
expect(parsed_response['included']['service_brokers'][0]['name']).to eq(service_1.service_broker.name)
706+
expect(parsed_response['included']['service_brokers'][1]['guid']).to eq(service_2.service_broker.guid)
707+
expect(parsed_response['included']['service_brokers'][1]['name']).to eq(service_2.service_broker.name)
708+
end
709+
end
693710
end
694711

695712
describe 'DELETE /v3/service_offerings/:guid' do
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'spec_helper'
2+
require 'decorators/field_service_offering_service_broker_decorator'
3+
require 'field_decorator_spec_shared_examples'
4+
5+
module VCAP::CloudController
6+
RSpec.describe FieldServiceOfferingServiceBrokerDecorator do
7+
describe '.decorate' do
8+
let(:offering1) { Service.make }
9+
let(:offering2) { Service.make }
10+
11+
it 'decorated the given hash with broker name and guid' do
12+
undecorated_hash = { foo: 'bar', included: { monkeys: %w(zach greg) } }
13+
decorator = described_class.new({ 'service_broker': ['name', 'guid'] })
14+
15+
hash = decorator.decorate(undecorated_hash, [offering1, offering2])
16+
17+
expect(hash).to match({
18+
foo: 'bar',
19+
included: {
20+
monkeys: %w(zach greg),
21+
service_brokers: [
22+
{
23+
guid: offering1.service_broker.guid,
24+
name: offering1.service_broker.name
25+
},
26+
{
27+
guid: offering2.service_broker.guid,
28+
name: offering2.service_broker.name
29+
}
30+
]
31+
}
32+
})
33+
end
34+
35+
context 'when offerings are from the same broker' do
36+
let(:offering3) { Service.make(service_broker: offering1.service_broker) }
37+
38+
it 'does not duplicate the broker' do
39+
decorator = described_class.new({ 'service_broker': ['name'] })
40+
hash = decorator.decorate({}, [offering1, offering3])
41+
expect(hash[:included][:service_brokers]).to have(1).element
42+
end
43+
end
44+
end
45+
46+
describe '.match?' do
47+
it_behaves_like 'field decorator match?', 'service_broker', ['name', 'guid']
48+
end
49+
end
50+
end

spec/unit/messages/service_offerings_list_message_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'spec_helper'
22
require 'messages/service_offerings_list_message'
3+
require 'field_message_spec_shared_examples'
34

45
module VCAP::CloudController
56
RSpec.describe ServiceOfferingsListMessage do
@@ -71,6 +72,10 @@ module VCAP::CloudController
7172
expect(message.errors[:available]).to include("only accepts values 'true' or 'false'")
7273
end
7374
end
75+
76+
context 'fields' do
77+
it_behaves_like 'field query parameter', 'service_broker', 'guid,name'
78+
end
7479
end
7580
end
7681
end

0 commit comments

Comments
 (0)