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

Commit 6c5f962

Browse files
Derik EvangelistaBrian Butz
andauthored
v3(services): GET Credential binding object response (cloudfoundry#1769)
[#173129426](https://www.pivotaltracker.com/story/show/173129426) Co-authored-by: Brian Butz <bbutz@pivotal.io>
1 parent 9949b9d commit 6c5f962

8 files changed

Lines changed: 350 additions & 31 deletions

File tree

app/fetchers/service_credential_binding_fetcher.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
module VCAP
22
module CloudController
33
class ServiceCredentialBindingFetcher
4-
ServiceInstanceCredential = Struct.new(:guid, :type).freeze
5-
64
def fetch(guid, space_guids:)
7-
list_fetcher.fetch(space_guids: space_guids).first(guid: guid).try do |db_binding|
8-
ServiceInstanceCredential.new(
9-
db_binding.guid,
10-
db_binding.type
11-
)
12-
end
5+
list_fetcher.fetch(space_guids: space_guids).first(guid: guid)
136
end
147

158
private

app/models/services/service_credential_binding_view.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@ module Types
1010
Sequel.as(:service_keys__guid, :guid),
1111
Sequel.as(Types::SERVICE_KEY, :type),
1212
Sequel.as(:spaces__guid, :space_guid),
13-
Sequel.as(:service_keys__created_at, :created_at)
13+
Sequel.as(:service_keys__created_at, :created_at),
14+
Sequel.as(:service_keys__updated_at, :updated_at),
15+
Sequel.as(:service_keys__name, :name),
16+
Sequel.as(:service_instances__guid, :service_instance_guid),
17+
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)
1424
).join(
1525
:service_instances, id: Sequel[:service_keys][:service_instance_id]
1626
).join(
@@ -21,11 +31,23 @@ module Types
2131
Sequel.as(:service_bindings__guid, :guid),
2232
Sequel.as(Types::SERVICE_BINDING, :type),
2333
Sequel.as(:spaces__guid, :space_guid),
24-
Sequel.as(:service_bindings__created_at, :created_at)
34+
Sequel.as(:service_bindings__created_at, :created_at),
35+
Sequel.as(:service_bindings__updated_at, :updated_at),
36+
Sequel.as(:service_bindings__name, :name),
37+
Sequel.as(:service_bindings__service_instance_guid, :service_instance_guid),
38+
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)
2545
).join(
2646
:apps, guid: Sequel[:service_bindings][:app_guid]
2747
).join(
2848
:spaces, guid: Sequel[:apps][:space_guid]
49+
).left_join(
50+
:service_binding_operations, service_binding_id: Sequel[:service_bindings][:id]
2951
).freeze
3052

3153
VIEW = [

app/presenters/v3/base_presenter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'presenters/helpers/censorship'
2+
require 'presenters/api_url_builder'
23

34
module VCAP
45
module CloudController

app/presenters/v3/service_credential_binding_presenter.rb

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,64 @@ class ServiceCredentialBindingPresenter < BasePresenter
88
def to_hash
99
{
1010
guid: @resource.guid,
11-
type: @resource.type
11+
type: @resource.type,
12+
name: @resource.name,
13+
created_at: @resource.created_at,
14+
updated_at: @resource.updated_at,
15+
last_operation: last_operation,
16+
relationships: build_relationships,
17+
links: build_links
1218
}
1319
end
20+
21+
private
22+
23+
def build_relationships
24+
base_relationships.merge(app_relationship)
25+
end
26+
27+
def build_links
28+
base_links.merge(app_link)
29+
end
30+
31+
def last_operation
32+
return nil if @resource.last_operation_id.blank?
33+
34+
{
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
40+
}
41+
end
42+
43+
def base_links
44+
{
45+
self: { href: url_builder.build_url(path: "/v3/service_credential_bindings/#{@resource.guid}") },
46+
service_instance: {
47+
href: url_builder.build_url(path: "/v3/service_instances/#{@resource.service_instance_guid}")
48+
}
49+
}
50+
end
51+
52+
def base_relationships
53+
{
54+
service_instance: { data: { guid: @resource.service_instance_guid } }
55+
}
56+
end
57+
58+
def app_relationship
59+
return {} if @resource.app_guid.blank?
60+
61+
{ app: { data: { guid: @resource.app_guid } } }
62+
end
63+
64+
def app_link
65+
return {} if @resource.app_guid.blank?
66+
67+
{ app: { href: url_builder.build_url(path: "/v3/apps/#{@resource.app_guid}") } }
68+
end
1469
end
1570
end
1671
end

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

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,61 @@
11
<% content_for :single_service_credential_binding_app do %>
22
{
3-
"guid": "ddd7fb26-c42d-4acf-a035-60fdd094a167",
4-
"type": "app"
3+
"guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3",
4+
"type": "app",
5+
"created_at": "2015-11-13T17:02:56Z",
6+
"updated_at": "2016-06-08T16:41:26Z",
7+
"relationships": {
8+
"app": {
9+
"data": {
10+
"guid": "74f7c078-0934-470f-9883-4fddss5b8f13"
11+
}
12+
},
13+
"service_instances": {
14+
"data": {
15+
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
16+
}
17+
}
18+
},
19+
"links": {
20+
"self": {
21+
"href": "https://api.example.org/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3"
22+
},
23+
"service_instance": {
24+
"href": "https://api.example.org/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e"
25+
},
26+
"app": {
27+
"href": "https://api.example.org/v3/apps/74f7c078-0934-470f-9883-4fddss5b8f13"
28+
}
29+
}
530
}
631
<% end %>
732

833
<% content_for :single_service_credential_binding_key do %>
934
{
10-
"guid": "ddd7fb26-c42d-4acf-a035-60fdd094a167",
11-
"type": "key"
35+
"guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3",
36+
"type": "key",
37+
"created_at": "2015-11-13T17:02:56Z",
38+
"updated_at": "2016-06-08T16:41:26Z",
39+
"relationships": {
40+
"service_instances": {
41+
"data": {
42+
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
43+
}
44+
}
45+
},
46+
"links": {
47+
"self": {
48+
"href": "https://api.example.org/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3"
49+
},
50+
"service_instance": {
51+
"href": "https://api.example.org/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e"
52+
}
53+
}
1254
}
1355
<% end %>
1456

1557
<% content_for :paginated_list_of_service_credential_bindings do |base_url| %>
16-
{
58+
{
1759
"pagination": {
1860
"total_results": 3,
1961
"total_pages": 2,
@@ -31,11 +73,61 @@
3173
"resources": [
3274
{
3375
"guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3",
34-
"type": "app"
76+
"type": "app",
77+
"created_at": "2015-11-13T17:02:56Z",
78+
"updated_at": "2016-06-08T16:41:26Z",
79+
"last_operation": {
80+
"type": "create",
81+
"state": "succeeded",
82+
"created_at": "2015-11-13T17:02:56Z",
83+
"created_at": "2015-11-13T17:02:56Z",
84+
"updated_at": "2015-11-13T17:02:56Z"
85+
},
86+
"relationships": {
87+
"app": {
88+
"data": {
89+
"guid": "74f7c078-0934-470f-9883-4fddss5b8f13"
90+
}
91+
},
92+
"service_instances": {
93+
"data": {
94+
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
95+
}
96+
}
97+
},
98+
"links": {
99+
"self": {
100+
"href": "https://api.example.org/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3"
101+
},
102+
"service_instance": {
103+
"href": "https://api.example.org/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e"
104+
},
105+
"app": {
106+
"href": "https://api.example.org/v3/apps/74f7c078-0934-470f-9883-4fddss5b8f13"
107+
}
108+
}
35109
},
36110
{
37111
"guid": "7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62",
38-
"type": "key"
112+
"type": "key",
113+
"created_at": "2015-11-13T17:02:56Z",
114+
"updated_at": "2016-06-08T16:41:26Z",
115+
"last_operation": null,
116+
"relationships": {
117+
"service_instances": {
118+
"data": {
119+
"guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e"
120+
}
121+
}
122+
},
123+
"links": {
124+
"self": {
125+
"href": "https://api.example.org/v3/service_bindings/7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62"
126+
},
127+
"service_instance": {
128+
"href": "https://api.example.org/v3/service_instances/8bf356j3-9e18-45b1-3333-124163f31f9e"
129+
}
130+
}
39131
}
40132
]
41133
}

spec/request/service_credential_bindings_spec.rb

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
let(:key) { VCAP::CloudController::ServiceKey.make(service_instance: instance) }
7575
let(:instance) { VCAP::CloudController::ManagedServiceInstance.make(space: space) }
7676
let(:api_call) { ->(user_headers) { get "/v3/service_credential_bindings/#{key.guid}", nil, user_headers } }
77-
let(:expected_object) { { guid: key.guid, type: 'key' } }
77+
let(:expected_object) { expected_json(key) }
7878

7979
context 'global roles' do
8080
let(:expected_codes_and_responses) do
@@ -117,10 +117,18 @@
117117

118118
describe 'GET /v3/service_credential_bindings/:app_guid' do
119119
let(:app_to_bind_to) { VCAP::CloudController::AppModel.make(space: space) }
120-
let(:app_binding) { VCAP::CloudController::ServiceBinding.make(service_instance: instance, app: app_to_bind_to) }
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+
}
121129
let(:instance) { VCAP::CloudController::ManagedServiceInstance.make(space: space) }
122130
let(:api_call) { ->(user_headers) { get "/v3/service_credential_bindings/#{app_binding.guid}", nil, user_headers } }
123-
let(:expected_object) { { guid: app_binding.guid, type: 'app' } }
131+
let(:expected_object) { expected_json(app_binding) }
124132

125133
context 'global roles' do
126134
let(:expected_codes_and_responses) do
@@ -169,19 +177,60 @@
169177

170178
def expected_json(binding)
171179
{
172-
guid: binding.guid
173-
}.merge(extra(binding))
180+
guid: binding.guid,
181+
created_at: iso8601,
182+
updated_at: iso8601,
183+
name: binding.name,
184+
last_operation: nil,
185+
relationships: {
186+
service_instance: {
187+
data: {
188+
guid: binding.service_instance.guid
189+
}
190+
}
191+
},
192+
links: {
193+
self: {
194+
href: "#{link_prefix}/v3/service_credential_bindings/#{binding.guid}"
195+
},
196+
service_instance: {
197+
href: "#{link_prefix}/v3/service_instances/#{binding.service_instance.guid}"
198+
}
199+
}
200+
}.deep_merge(extra(binding))
174201
end
175202

176203
def extra(binding)
177204
case binding
178205
when VCAP::CloudController::ServiceKey
179206
{
180-
type: 'key'
207+
type: 'key',
181208
}
182209
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
183219
{
184-
type: 'app'
220+
type: 'app',
221+
last_operation: last_operation,
222+
relationships: {
223+
app: {
224+
data: {
225+
guid: binding.app.guid
226+
}
227+
}
228+
},
229+
links: {
230+
app: {
231+
href: "#{link_prefix}/v3/apps/#{binding.app.guid}"
232+
}
233+
}
185234
}
186235
else
187236
raise 'not a binding'

0 commit comments

Comments
 (0)