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

Commit 0afcf83

Browse files
Urse SearleBrian Butz
authored andcommitted
v3(services): Allow users to get a list of route bindings
[#174192797](https://www.pivotaltracker.com/story/show/174192797) Signed-off-by: Brian Butz <bbutz@pivotal.io>
1 parent d7bf7cd commit 0afcf83

5 files changed

Lines changed: 152 additions & 1 deletion

File tree

app/controllers/v3/service_route_bindings_controller.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'actions/service_route_binding_create'
33
require 'jobs/v3/create_route_binding_job'
44
require 'presenters/v3/service_route_binding_presenter'
5+
require 'fetchers/route_binding_list_fetcher'
56

67
class ServiceRouteBindingsController < ApplicationController
78
def create
@@ -40,8 +41,32 @@ def show
4041
render status: :ok, json: Presenters::V3::ServiceRouteBindingPresenter.new(route_binding)
4142
end
4243

44+
def index
45+
route_bindings = fetch_route_bindings
46+
message = ListMessage.from_params(query_params, [])
47+
render status: :ok, json: Presenters::V3::PaginatedListPresenter.new(
48+
presenter: Presenters::V3::ServiceRouteBindingPresenter,
49+
paginated_result: SequelPaginator.new.get_page(route_bindings, message.try(:pagination_options)),
50+
path: '/v3/service_route_bindings',
51+
message: message,
52+
)
53+
end
54+
4355
private
4456

57+
def fetch_route_bindings
58+
fetcher = RouteBindingListFetcher.new
59+
if permission_queryer.can_read_globally?
60+
fetcher.fetch_all
61+
else
62+
fetcher.fetch_some(space_guids: space_guids)
63+
end
64+
end
65+
66+
def space_guids
67+
permission_queryer.readable_space_guids
68+
end
69+
4570
def parse_create_request
4671
message = ServiceRouteBindingCreateMessage.new(hashed_params[:body])
4772
unprocessable!(message.errors.full_messages) unless message.valid?
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module VCAP
2+
module CloudController
3+
class RouteBindingListFetcher
4+
def fetch_all
5+
RouteBinding.dataset
6+
end
7+
8+
def fetch_some(space_guids:)
9+
RouteBinding.dataset.
10+
join(:service_instances, id: Sequel[:route_bindings][:service_instance_id]).
11+
join(:spaces, id: Sequel[:service_instances][:space_id]).
12+
where { Sequel[:spaces][:guid] =~ space_guids }.
13+
select_all(:route_bindings)
14+
end
15+
end
16+
end
17+
end

config/routes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@
197197
# service_route_bindings
198198
resources :service_route_bindings,
199199
param: :guid,
200-
only: [:show, :create]
200+
only: [:show, :create, :index]
201201

202202
# service_brokers
203203
get '/service_brokers', to: 'service_brokers#index'

spec/request/service_route_bindings_spec.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,67 @@
641641
end
642642
end
643643

644+
describe 'GET /v3/service_route_bindings' do
645+
describe 'no bindings to list' do
646+
let(:api_call) { ->(user_headers) { get '/v3/service_route_bindings', nil, user_headers } }
647+
let(:expected_codes_and_responses) do
648+
Hash.new(code: 200, response_objects: [])
649+
end
650+
651+
it_behaves_like 'permissions for list endpoint', ALL_PERMISSIONS
652+
end
653+
654+
describe 'a mix of bindings' do
655+
let(:route) { VCAP::CloudController::Route.make(space: space) }
656+
let(:service_instance_1) { VCAP::CloudController::UserProvidedServiceInstance.make(:routing, space: space, route_service_url: route_service_url) }
657+
let(:service_instance_2) { VCAP::CloudController::ManagedServiceInstance.make(:routing, space: space, route_service_url: route_service_url) }
658+
let(:route_binding_1) do
659+
bind_service_to_route(service_instance_1, route)
660+
end
661+
let(:route_binding_2) do
662+
bind_service_to_route(service_instance_2, route)
663+
end
664+
let(:api_call) { ->(user_headers) { get '/v3/service_route_bindings', nil, user_headers } }
665+
let(:response_objects) do
666+
[
667+
expected_json(
668+
binding_guid: route_binding_1.guid,
669+
route_service_url: route_service_url,
670+
service_instance_guid: service_instance_1.guid,
671+
route_guid: route.guid,
672+
last_operation_type: 'create',
673+
last_operation_state: 'successful',
674+
),
675+
expected_json(
676+
binding_guid: route_binding_2.guid,
677+
route_service_url: route_service_url,
678+
service_instance_guid: service_instance_2.guid,
679+
route_guid: route.guid,
680+
last_operation_type: 'create',
681+
last_operation_state: 'successful',
682+
)
683+
]
684+
end
685+
let(:bindings_response_body) do
686+
{ code: 200, response_objects: response_objects }
687+
end
688+
689+
let(:expected_codes_and_responses) do
690+
Hash.new(code: 200, response_objects: []).tap do |h|
691+
h['admin'] = bindings_response_body
692+
h['admin_read_only'] = bindings_response_body
693+
h['global_auditor'] = bindings_response_body
694+
h['space_developer'] = bindings_response_body
695+
h['space_manager'] = bindings_response_body
696+
h['space_auditor'] = bindings_response_body
697+
h['org_manager'] = bindings_response_body
698+
end
699+
end
700+
701+
it_behaves_like 'permissions for list endpoint', ALL_PERMISSIONS
702+
end
703+
end
704+
644705
describe 'GET /v3/service_route_bindings/:guid' do
645706
let(:api_call) { ->(user_headers) { get "/v3/service_route_bindings/#{guid}", nil, user_headers } }
646707
let(:route) { VCAP::CloudController::Route.make(space: space) }
@@ -755,4 +816,12 @@ def expected_json(binding_guid:, route_service_url:, route_guid:, service_instan
755816
}
756817
}
757818
end
819+
820+
def bind_service_to_route(service_instance, route)
821+
route_service_url = service_instance.route_service_url
822+
VCAP::CloudController::RouteBinding.new.save_with_new_operation(
823+
{ service_instance: service_instance, route: route, route_service_url: route_service_url },
824+
{ type: 'create', state: 'successful' }
825+
)
826+
end
758827
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
require 'spec_helper'
2+
3+
module VCAP
4+
module CloudController
5+
RSpec.describe RouteBindingListFetcher do
6+
let(:fetcher) { RouteBindingListFetcher.new }
7+
8+
describe 'fetch_all' do
9+
it 'should return all route bindings' do
10+
route_bindings = Array.new(3) { RouteBinding.make }
11+
12+
fetched_route_bindings = fetcher.fetch_all
13+
14+
fetched_route_binding_guids = fetched_route_bindings.map(&:guid)
15+
expected_route_binding_guids = route_bindings.map(&:guid)
16+
expect(fetched_route_binding_guids).to eq(expected_route_binding_guids)
17+
end
18+
end
19+
20+
describe 'fetch_some' do
21+
it 'it should return route bindings related to a set of space guids' do
22+
target_space = Space.make
23+
service_instance_in_target_space = UserProvidedServiceInstance.make(:routing, space: target_space)
24+
make_other_route_bindings
25+
route_bindings_in_target_space = Array.new(3) { RouteBinding.make(service_instance: service_instance_in_target_space) }
26+
27+
fetched_route_bindings = fetcher.fetch_some(space_guids: [target_space.guid])
28+
29+
fetched_route_binding_guids = fetched_route_bindings.map(&:guid)
30+
target_space_route_binding_guids = route_bindings_in_target_space.map(&:guid)
31+
expect(fetched_route_binding_guids).to eq(target_space_route_binding_guids)
32+
end
33+
34+
def make_other_route_bindings
35+
Array.new(3) { RouteBinding.make }
36+
end
37+
end
38+
end
39+
end
40+
end

0 commit comments

Comments
 (0)