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

Commit 8dc560b

Browse files
author
Brian Butz
authored
v3(services): cred binding list body (cloudfoundry#1771)
* v3(services): Have cred binding view return ServiceBinding and ServiceKey objects [#174034068](https://www.pivotaltracker.com/story/show/174034068)
1 parent 209323a commit 8dc560b

7 files changed

Lines changed: 203 additions & 137 deletions

File tree

app/models/services/service_credential_binding_view.rb

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Types
77
end
88

99
SERVICE_KEY_VIEW = Sequel::Model(:service_keys).select(
10+
Sequel.as(:service_keys__id, :id),
1011
Sequel.as(:service_keys__guid, :guid),
1112
Sequel.as(Types::SERVICE_KEY, :type),
1213
Sequel.as(:spaces__guid, :space_guid),
@@ -15,19 +16,15 @@ module Types
1516
Sequel.as(:service_keys__name, :name),
1617
Sequel.as(:service_instances__guid, :service_instance_guid),
1718
Sequel.as(nil, :app_guid),
18-
Sequel.as(nil, :last_operation_state),
19-
Sequel.as(nil, :last_operation_description),
20-
Sequel.as(nil, :last_operation_created_at),
21-
Sequel.as(nil, :last_operation_updated_at),
22-
Sequel.as(nil, :last_operation_type),
23-
Sequel.as(nil, :last_operation_id)
19+
Sequel.as(:service_keys__service_instance_id, :service_instance_id)
2420
).join(
2521
:service_instances, id: Sequel[:service_keys][:service_instance_id]
2622
).join(
2723
:spaces, id: Sequel[:service_instances][:space_id]
2824
).freeze
2925

3026
SERVICE_BINDING_VIEW = Sequel::Model(:service_bindings).select(
27+
Sequel.as(:service_bindings__id, :id),
3128
Sequel.as(:service_bindings__guid, :guid),
3229
Sequel.as(Types::SERVICE_BINDING, :type),
3330
Sequel.as(:spaces__guid, :space_guid),
@@ -36,18 +33,11 @@ module Types
3633
Sequel.as(:service_bindings__name, :name),
3734
Sequel.as(:service_bindings__service_instance_guid, :service_instance_guid),
3835
Sequel.as(:service_bindings__app_guid, :app_guid),
39-
Sequel.as(:service_binding_operations__state, :last_operation_state),
40-
Sequel.as(:service_binding_operations__description, :last_operation_description),
41-
Sequel.as(:service_binding_operations__created_at, :last_operation_created_at),
42-
Sequel.as(:service_binding_operations__updated_at, :last_operation_updated_at),
43-
Sequel.as(:service_binding_operations__type, :last_operation_type),
44-
Sequel.as(:service_binding_operations__id, :last_operation_id)
36+
Sequel.as(nil, :service_instance_id)
4537
).join(
4638
:apps, guid: Sequel[:service_bindings][:app_guid]
4739
).join(
4840
:spaces, guid: Sequel[:apps][:space_guid]
49-
).left_join(
50-
:service_binding_operations, service_binding_id: Sequel[:service_bindings][:id]
5141
).freeze
5242

5343
VIEW = [
@@ -58,6 +48,12 @@ module Types
5848
end.from_self.freeze
5949

6050
class View < Sequel::Model(VIEW)
51+
plugin :single_table_inheritance,
52+
:type,
53+
model_map: {
54+
'app' => 'VCAP::CloudController::ServiceBinding',
55+
'key' => 'VCAP::CloudController::ServiceKey'
56+
}
6157
end
6258
end
6359
end

app/presenters/v3/service_credential_binding_presenter.rb

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,52 @@ class ServiceCredentialBindingPresenter < BasePresenter
88
def to_hash
99
{
1010
guid: @resource.guid,
11-
type: @resource.type,
1211
name: @resource.name,
1312
created_at: @resource.created_at,
1413
updated_at: @resource.updated_at,
15-
last_operation: last_operation,
16-
relationships: build_relationships,
17-
links: build_links
18-
}
14+
type: type
15+
}.merge(extra)
1916
end
2017

2118
private
2219

23-
def build_relationships
24-
base_relationships.merge(app_relationship)
20+
def type
21+
case @resource
22+
when VCAP::CloudController::ServiceKey
23+
'key'
24+
when VCAP::CloudController::ServiceBinding
25+
'app'
26+
end
2527
end
2628

27-
def build_links
28-
base_links.merge(app_link)
29+
def extra
30+
case type
31+
when 'app'
32+
{
33+
last_operation: last_operation,
34+
relationships: base_relationships.merge(app_relationship),
35+
links: base_links.merge(app_link)
36+
}
37+
when 'key'
38+
{
39+
last_operation: nil,
40+
relationships: base_relationships,
41+
links: base_links
42+
}
43+
end
2944
end
3045

3146
def last_operation
32-
return nil if @resource.last_operation_id.blank?
47+
return nil if @resource.last_operation.blank?
48+
49+
last_operation = @resource.last_operation
3350

3451
{
35-
type: @resource.last_operation_type,
36-
state: @resource.last_operation_state,
37-
description: @resource.last_operation_description,
38-
created_at: @resource.last_operation_created_at,
39-
updated_at: @resource.last_operation_updated_at
52+
type: last_operation.type,
53+
state: last_operation.state,
54+
description: last_operation.description,
55+
created_at: last_operation.created_at,
56+
updated_at: last_operation.updated_at
4057
}
4158
end
4259

docs/v3/source/includes/api_resources/_service_credential_bindings.erb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"guid": "74f7c078-0934-470f-9883-4fddss5b8f13"
1111
}
1212
},
13-
"service_instances": {
13+
"service_instance": {
1414
"data": {
1515
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
1616
}
@@ -37,7 +37,7 @@
3737
"created_at": "2015-11-13T17:02:56Z",
3838
"updated_at": "2016-06-08T16:41:26Z",
3939
"relationships": {
40-
"service_instances": {
40+
"service_instance": {
4141
"data": {
4242
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
4343
}
@@ -89,7 +89,7 @@
8989
"guid": "74f7c078-0934-470f-9883-4fddss5b8f13"
9090
}
9191
},
92-
"service_instances": {
92+
"service_instance": {
9393
"data": {
9494
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
9595
}
@@ -114,7 +114,7 @@
114114
"updated_at": "2016-06-08T16:41:26Z",
115115
"last_operation": null,
116116
"relationships": {
117-
"service_instances": {
117+
"service_instance": {
118118
"data": {
119119
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
120120
}

spec/request/service_credential_bindings_spec.rb

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
let(:other_instance) { VCAP::CloudController::ManagedServiceInstance.make(space: other_space) }
1414
let!(:key_binding) { VCAP::CloudController::ServiceKey.make(service_instance: instance, created_at: now - 4.seconds) }
1515
let!(:other_key_binding) { VCAP::CloudController::ServiceKey.make(service_instance: other_instance, created_at: now - 3.seconds) }
16-
let!(:app_binding) { VCAP::CloudController::ServiceBinding.make(service_instance: instance, created_at: now - 2.seconds) }
16+
let!(:app_binding) do
17+
VCAP::CloudController::ServiceBinding.make(service_instance: instance, created_at: now - 2.seconds).tap do |binding|
18+
operate_on(binding)
19+
end
20+
end
1721
let!(:other_app_binding) { VCAP::CloudController::ServiceBinding.make(service_instance: other_instance, created_at: now - 1.second) }
1822

1923
describe 'permissions' do
@@ -117,15 +121,11 @@
117121

118122
describe 'GET /v3/service_credential_bindings/:app_guid' do
119123
let(:app_to_bind_to) { VCAP::CloudController::AppModel.make(space: space) }
120-
let(:app_binding) {
121-
b = VCAP::CloudController::ServiceBinding.make(service_instance: instance, app: app_to_bind_to)
122-
b.save_with_new_operation({
123-
type: 'create',
124-
state: 'succeeded',
125-
description: 'some description'
126-
})
127-
b
128-
}
124+
let(:app_binding) do
125+
VCAP::CloudController::ServiceBinding.make(service_instance: instance, app: app_to_bind_to).tap do |binding|
126+
operate_on(binding)
127+
end
128+
end
129129
let(:instance) { VCAP::CloudController::ManagedServiceInstance.make(space: space) }
130130
let(:api_call) { ->(user_headers) { get "/v3/service_credential_bindings/#{app_binding.guid}", nil, user_headers } }
131131
let(:expected_object) { expected_json(app_binding) }
@@ -207,18 +207,9 @@ def extra(binding)
207207
type: 'key',
208208
}
209209
when VCAP::CloudController::ServiceBinding
210-
if binding.last_operation.present?
211-
last_operation = {
212-
type: binding.last_operation.type,
213-
state: binding.last_operation.state,
214-
description: binding.last_operation.description,
215-
created_at: iso8601,
216-
updated_at: iso8601
217-
}
218-
end
219210
{
220211
type: 'app',
221-
last_operation: last_operation,
212+
last_operation: last_operation(binding),
222213
relationships: {
223214
app: {
224215
data: {
@@ -236,4 +227,26 @@ def extra(binding)
236227
raise 'not a binding'
237228
end
238229
end
230+
231+
def last_operation(binding)
232+
if binding.last_operation.present?
233+
{
234+
type: binding.last_operation.type,
235+
state: binding.last_operation.state,
236+
description: binding.last_operation.description,
237+
created_at: iso8601,
238+
updated_at: iso8601
239+
}
240+
end
241+
end
242+
243+
def operate_on(binding)
244+
binding.save_with_new_operation(
245+
{
246+
type: 'create',
247+
state: 'succeeded',
248+
description: 'some description'
249+
}
250+
)
251+
end
239252
end

spec/unit/fetchers/service_credential_binding_fetcher_spec.rb

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module CloudController
1616
end
1717

1818
describe 'service keys' do
19-
let(:type) { 'key' }
2019
let(:space) { Space.make }
2120
let(:service_instance) { ManagedServiceInstance.make(space: space) }
2221
let!(:service_key) { ServiceKey.make(service_instance: service_instance) }
@@ -26,13 +25,11 @@ module CloudController
2625
credential_binding = fetcher.fetch(service_key.guid, space_guids: [space.guid])
2726

2827
expect(credential_binding).not_to be_nil
29-
expect(credential_binding.type).to eql(type)
28+
expect(credential_binding).to an_instance_of(VCAP::CloudController::ServiceKey)
3029
expect(credential_binding.name).to eql(service_key.name)
3130
expect(credential_binding.created_at).to eql(service_key.created_at)
3231
expect(credential_binding.updated_at).to eql(service_key.updated_at)
3332
expect(credential_binding.service_instance_guid).to eql(service_instance.guid)
34-
expect(credential_binding.app_guid).to be_nil
35-
expect(credential_binding.last_operation_id).to be_nil
3633
end
3734
end
3835

@@ -47,8 +44,6 @@ module CloudController
4744
end
4845

4946
describe 'app bindings' do
50-
let(:type) { 'app' }
51-
5247
describe 'managed services' do
5348
let(:space) { Space.make }
5449
let(:service_instance) { ManagedServiceInstance.make(space: space) }
@@ -58,13 +53,13 @@ module CloudController
5853
credential_binding = fetcher.fetch(app_binding.guid, space_guids: [space.guid])
5954

6055
expect(credential_binding).not_to be_nil
61-
expect(credential_binding.type).to eql(type)
56+
expect(credential_binding).to an_instance_of(VCAP::CloudController::ServiceBinding)
6257
expect(credential_binding.name).to eql('some-name')
6358
expect(credential_binding.created_at).to eql(app_binding.created_at)
6459
expect(credential_binding.updated_at).to eql(app_binding.updated_at)
6560
expect(credential_binding.service_instance_guid).to eql(service_instance.guid)
6661
expect(credential_binding.app_guid).to eql(app_binding.app_guid)
67-
expect(credential_binding.last_operation_id).to be_nil
62+
expect(credential_binding.last_operation).to be_nil
6863
end
6964

7065
describe 'when not in the space' do
@@ -86,13 +81,13 @@ module CloudController
8681
credential_binding = fetcher.fetch(app_binding.guid, space_guids: [space.guid])
8782

8883
expect(credential_binding).not_to be_nil
89-
expect(credential_binding.type).to eql(type)
84+
expect(credential_binding).to an_instance_of(VCAP::CloudController::ServiceBinding)
9085
expect(credential_binding.name).to eql('some-name')
9186
expect(credential_binding.created_at).to eql(app_binding.created_at)
9287
expect(credential_binding.updated_at).to eql(app_binding.updated_at)
9388
expect(credential_binding.service_instance_guid).to eql(service_instance.guid)
9489
expect(credential_binding.app_guid).to eql(app_binding.app_guid)
95-
expect(credential_binding.last_operation_id).to be_nil
90+
expect(credential_binding.last_operation).to be_nil
9691
end
9792

9893
describe 'when not in the space' do
@@ -112,15 +107,19 @@ module CloudController
112107
binding.save_with_new_operation({ state: 'succeeded', type: 'create', description: 'radical avocado' })
113108
binding
114109
}
110+
115111
it 'fetches the last operation' do
116112
credential_binding = fetcher.fetch(app_binding.guid, space_guids: [service_instance.space.guid])
117113

118-
expect(credential_binding.last_operation_id).to_not be_nil
119-
expect(credential_binding.last_operation_type).to eql('create')
120-
expect(credential_binding.last_operation_state).to eql('succeeded')
121-
expect(credential_binding.last_operation_description).to eql('radical avocado')
122-
expect(credential_binding.last_operation_created_at).to eql(app_binding.last_operation.created_at)
123-
expect(credential_binding.last_operation_updated_at).to eql(app_binding.last_operation.updated_at)
114+
expect(credential_binding.last_operation).to_not be_nil
115+
116+
last_operation = credential_binding.last_operation
117+
118+
expect(last_operation.type).to eql('create')
119+
expect(last_operation.state).to eql('succeeded')
120+
expect(last_operation.description).to eql('radical avocado')
121+
expect(last_operation.created_at).to eql(app_binding.last_operation.created_at)
122+
expect(last_operation.updated_at).to eql(app_binding.last_operation.updated_at)
124123
end
125124
end
126125
end

spec/unit/fetchers/service_credential_binding_list_fetcher_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,31 @@ module CloudController
4141
end
4242
end
4343
end
44+
45+
describe 'fetching app bindings' do
46+
let!(:app_binding) { VCAP::CloudController::ServiceBinding.make }
47+
48+
it 'allows the last operation to be accessed' do
49+
app_binding.save_with_new_operation(
50+
{
51+
type: 'create',
52+
state: 'succeeded',
53+
description: 'some description'
54+
}
55+
)
56+
57+
credential_binding = fetcher.fetch(space_guids: :all).first
58+
last_operation = credential_binding.last_operation
59+
60+
expect(last_operation).to be_present
61+
62+
expect(last_operation.type).to eql 'create'
63+
expect(last_operation.state).to eql 'succeeded'
64+
expect(last_operation.description).to eql 'some description'
65+
expect(last_operation.created_at).to be_present
66+
expect(last_operation.updated_at).to be_present
67+
end
68+
end
4469
end
4570
end
4671
end

0 commit comments

Comments
 (0)