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

Commit d063890

Browse files
author
Derik Evangelista
authored
v3(bindings): allow the binding SI to be included (cloudfoundry#1795)
Get and list endpoints [#173172605](https://www.pivotaltracker.com/story/show/173172605)
1 parent 7a1cbc6 commit d063890

11 files changed

Lines changed: 106 additions & 13 deletions

app/controllers/v3/service_credential_bindings_controller.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'messages/service_credential_bindings_list_message'
55
require 'messages/service_credential_bindings_show_message'
66
require 'decorators/include_binding_app_decorator'
7+
require 'decorators/include_binding_service_instance_decorator'
78

89
class ServiceCredentialBindingsController < ApplicationController
910
def index
@@ -35,7 +36,8 @@ def show
3536
private
3637

3738
AVAILABLE_DECORATORS = [
38-
IncludeBindingAppDecorator
39+
IncludeBindingAppDecorator,
40+
IncludeBindingServiceInstanceDecorator
3941
].freeze
4042

4143
def decorators(message)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module VCAP::CloudController
2+
class IncludeBindingServiceInstanceDecorator
3+
class << self
4+
def match?(include)
5+
include&.any? { |i| %w(service_instance).include?(i) }
6+
end
7+
8+
def decorate(hash, bindings)
9+
hash.deep_merge({
10+
included: {
11+
service_instances: service_instances(bindings).map { |i| Presenters::V3::ServiceInstancePresenter.new(i).to_hash }
12+
}
13+
})
14+
end
15+
16+
private
17+
18+
def service_instances(bindings)
19+
ServiceInstance.where(guid: bindings.map { |b| b[:service_instance_guid] }).order(:created_at)
20+
end
21+
end
22+
end
23+
end

app/messages/service_credential_bindings_list_message.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ServiceCredentialBindingsListMessage < ListMessage
1919

2020
validates_with NoAdditionalParamsValidator
2121
validates :type, allow_nil: true, inclusion: { in: %w(app key), message: "must be one of 'app', 'key'" }
22-
validates_with IncludeParamValidator, valid_values: %w(app)
22+
validates_with IncludeParamValidator, valid_values: %w(app service_instance)
2323

2424
def self.from_params(params)
2525
super(params, ARRAY_KEYS.map(&:to_s))

app/messages/service_credential_bindings_show_message.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class ServiceCredentialBindingsShowMessage < BaseMessage
99
register_allowed_keys ARRAY_KEYS
1010

1111
validates_with NoAdditionalParamsValidator
12-
validates_with IncludeParamValidator, valid_values: %w(app)
12+
validates_with IncludeParamValidator, valid_values: %w(app service_instance)
1313

1414
def self.from_params(params)
1515
super(params, ARRAY_KEYS.map(&:to_s))

docs/v3/source/includes/experimental_resources/service_credential_bindings/_get.md.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ This endpoint retrieves the service credential binding by GUID.
4242

4343
Name | Type | Description
4444
---- | ---- | ------------
45-
**include** | _list of strings_ | Optionally include a list of unique related resources in the response. Valid values are: `app`
45+
**include** | _list of strings_ | Optionally include a list of unique related resources in the response. Valid values are: `app`, `service_instance`
4646

4747
#### Permitted roles
4848
|

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Name | Type | Description
3737
**app_guids** | _list of strings_ | Comma-delimited list of app guids to filter by
3838
**app_names** | _strings_ | Type of credential binding to filter by. Valid values are: `app` or `key`
3939
**type** | _list of strings_ | Comma-delimited list of app names to filter by
40-
**include** | _list of strings_ | Optionally include a list of unique related resources in the response. Valid values are: `app`
40+
**include** | _list of strings_ | Optionally include a list of unique related resources in the response. Valid values are: `app`, `service_instance`
4141
**page** | _integer_ | Page to display; valid values are integers >= 1
4242
**per_page** | _integer_ | Number of results per page; <br>valid values are 1 through 5000
4343
**order_by** | _string_ | Value to sort by. Defaults to ascending; prepend with `-` to sort descending<br>Valid values are `created_at`, `updated_at`, and `name`

spec/request/service_credential_bindings_spec.rb

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,15 @@ def check_filtered_bindings(*bindings)
241241
expect(guids).to contain_exactly(app_binding.app.guid, other_app_binding.app.guid)
242242
end
243243

244+
it 'can include `service_instance`' do
245+
get '/v3/service_credential_bindings?include=service_instance', nil, admin_headers
246+
expect(last_response).to have_status_code(200)
247+
248+
expect(parsed_response['included']['service_instances']).to have(2).items
249+
guids = parsed_response['included']['service_instances'].map { |x| x['guid'] }
250+
expect(guids).to contain_exactly(instance.guid, other_instance.guid)
251+
end
252+
244253
it 'returns a 400 for invalid includes' do
245254
get '/v3/service_credential_bindings?include=routes', nil, admin_headers
246255
expect(last_response).to have_status_code(400)
@@ -312,9 +321,17 @@ def check_filtered_bindings(*bindings)
312321
it 'can include `app`' do
313322
get "/v3/service_credential_bindings/#{key.guid}?include=app", nil, admin_headers
314323
expect(last_response).to have_status_code(200)
315-
316324
expect(parsed_response['included']['apps']).to have(0).items
317325
end
326+
327+
it 'can include `service_instance`' do
328+
get "/v3/service_credential_bindings/#{key.guid}?include=service_instance", nil, admin_headers
329+
expect(last_response).to have_status_code(200)
330+
331+
expect(parsed_response['included']['service_instances']).to have(1).items
332+
guids = parsed_response['included']['service_instances'].map { |x| x['guid'] }
333+
expect(guids).to contain_exactly(instance.guid)
334+
end
318335
end
319336
end
320337
end
@@ -383,6 +400,15 @@ def check_filtered_bindings(*bindings)
383400
guids = parsed_response['included']['apps'].map { |x| x['guid'] }
384401
expect(guids).to contain_exactly(app_to_bind_to.guid)
385402
end
403+
404+
it 'can include `service_instance`' do
405+
get "/v3/service_credential_bindings/#{app_binding.guid}?include=service_instance", nil, admin_headers
406+
expect(last_response).to have_status_code(200)
407+
408+
expect(parsed_response['included']['service_instances']).to have(1).items
409+
guids = parsed_response['included']['service_instances'].map { |x| x['guid'] }
410+
expect(guids).to contain_exactly(instance.guid)
411+
end
386412
end
387413
end
388414

spec/unit/decorators/include_binding_app_decorator_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module VCAP::CloudController
99
bindings.map { |b| Presenters::V3::AppPresenter.new(b.app).to_hash }
1010
}
1111

12-
it 'decorates the given hash with organizations from apps' do
12+
it 'decorates the given hash with apps from bindings' do
1313
dict = { foo: 'bar' }
1414
hash = subject.decorate(dict, bindings)
1515
expect(hash[:foo]).to eq('bar')
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require 'spec_helper'
2+
require 'decorators/include_binding_service_instance_decorator'
3+
4+
module VCAP::CloudController
5+
RSpec.describe IncludeBindingServiceInstanceDecorator do
6+
subject(:decorator) { described_class }
7+
let(:bindings) { [ServiceBinding.make, ServiceBinding.make, ServiceBinding.make] }
8+
let(:instances) {
9+
bindings.map { |b| Presenters::V3::ServiceInstancePresenter.new(b.service_instance).to_hash }
10+
}
11+
12+
it 'decorates the given hash with service instances from bindings' do
13+
dict = { foo: 'bar' }
14+
hash = subject.decorate(dict, bindings)
15+
expect(hash[:foo]).to eq('bar')
16+
expect(hash[:included][:service_instances]).to match_array(instances)
17+
end
18+
19+
it 'does not overwrite other included fields' do
20+
dict = { foo: 'bar', included: { fruits: ['tomato', 'banana'] } }
21+
hash = subject.decorate(dict, bindings)
22+
expect(hash[:foo]).to eq('bar')
23+
expect(hash[:included][:service_instances]).to match_array(instances)
24+
expect(hash[:included][:fruits]).to match_array(['tomato', 'banana'])
25+
end
26+
27+
it 'does not include duplicates' do
28+
hash = subject.decorate({}, bindings << ServiceBinding.make(service_instance: bindings[0].service_instance))
29+
expect(hash[:included][:service_instances]).to have(3).items
30+
end
31+
32+
describe '.match?' do
33+
it 'matches include arrays containing "app"' do
34+
expect(decorator.match?(['potato', 'service_instance', 'turnip'])).to be_truthy
35+
end
36+
37+
it 'does not match other include arrays' do
38+
expect(decorator.match?(['potato', 'turnip'])).to be_falsey
39+
end
40+
end
41+
end
42+
end

spec/unit/messages/service_credential_bindings_list_message_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module VCAP::CloudController
1616
'app_guids' => 'app-1-guid, app-2-guid, app-3-guid',
1717
'app_names' => 'app-1-name, app-2-name, app-3-name',
1818
'type' => 'app',
19-
'include' => 'app'
19+
'include' => 'app,service_instance'
2020
}
2121
end
2222

@@ -32,7 +32,7 @@ module VCAP::CloudController
3232
expect(message.app_guids).to match_array(['app-1-guid', 'app-2-guid', 'app-3-guid'])
3333
expect(message.app_names).to match_array(['app-1-name', 'app-2-name', 'app-3-name'])
3434
expect(message.type).to eq('app')
35-
expect(message.include).to match_array(['app'])
35+
expect(message.include).to match_array(['app', 'service_instance'])
3636
end
3737

3838
it 'converts requested keys to symbols' do
@@ -87,7 +87,7 @@ module VCAP::CloudController
8787
end
8888

8989
it 'returns true for valid values' do
90-
message = described_class.from_params({ 'include' => 'app' })
90+
message = described_class.from_params({ 'include' => 'app, service_instance' })
9191
expect(message).to be_valid
9292
end
9393
end

0 commit comments

Comments
 (0)