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

Commit a129c1f

Browse files
committed
v3(services): make offering fetcher like plan fetcher
We wrote the service offering fetcher before the service plan fetcher, and learnt some lessons while doing it which we applied to the service plan fetcher. This change applies those lessons to the service offering fetcher, pulling common code into a new base class. [#171435755](https://www.pivotaltracker.com/story/show/171435755)
1 parent f150687 commit a129c1f

File tree

8 files changed

+662
-810
lines changed

8 files changed

+662
-810
lines changed

app/controllers/v3/service_offerings_controller.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ def index
2121
invalid_param!(message.errors.full_messages) unless message.valid?
2222

2323
dataset = if !current_user
24-
ServiceOfferingListFetcher.fetch_public(message)
25-
elsif permission_queryer.can_read_globally?
2624
ServiceOfferingListFetcher.fetch(message)
25+
elsif permission_queryer.can_read_globally?
26+
ServiceOfferingListFetcher.fetch(message, omniscient: true)
2727
else
28-
ServiceOfferingListFetcher.fetch_visible(
28+
ServiceOfferingListFetcher.fetch(
2929
message,
30-
permission_queryer.readable_org_guids,
31-
permission_queryer.readable_space_scoped_space_guids,
30+
readable_org_guids: permission_queryer.readable_org_guids,
31+
readable_space_guids: permission_queryer.readable_space_scoped_space_guids,
3232
)
3333
end
3434

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
require 'set'
2+
require 'fetchers/base_list_fetcher'
3+
require 'fetchers/label_selector_query_generator'
4+
5+
module VCAP::CloudController
6+
class BaseServiceListFetcher < BaseListFetcher
7+
class << self
8+
private
9+
10+
def select_readable(dataset, omniscient: false, readable_space_guids: [], readable_org_guids: [])
11+
if readable_org_guids.any?
12+
dataset = dataset.where do
13+
(Sequel[:service_plans][:public] =~ true) |
14+
(Sequel[:plan_orgs][:guid] =~ readable_org_guids) |
15+
(Sequel[:broker_spaces][:guid] =~ readable_space_guids)
16+
end
17+
elsif !omniscient
18+
dataset = dataset.where { Sequel[:service_plans][:public] =~ true }
19+
end
20+
21+
dataset
22+
end
23+
24+
def filter(message, dataset, klass)
25+
if message.requested?(:service_broker_guids)
26+
dataset = dataset.where { Sequel[:service_brokers][:guid] =~ message.service_broker_guids }
27+
end
28+
29+
if message.requested?(:service_broker_names)
30+
dataset = dataset.where { Sequel[:service_brokers][:name] =~ message.service_broker_names }
31+
end
32+
33+
super(message, dataset, klass)
34+
end
35+
36+
def filter_orgs(dataset, organization_guids)
37+
dataset.where do
38+
(Sequel[:service_plans][:public] =~ true) |
39+
(Sequel[:plan_orgs][:guid] =~ organization_guids) |
40+
(Sequel[:broker_orgs][:guid] =~ organization_guids)
41+
end
42+
end
43+
44+
def filter_spaces(dataset, filtered_space_guids:, readable_space_guids:, omniscient:)
45+
space_guids = authorized_space_guids(
46+
space_guids: filtered_space_guids,
47+
readable_space_guids: readable_space_guids,
48+
omniscient: omniscient,
49+
)
50+
51+
dataset.where do
52+
(Sequel[:service_plans][:public] =~ true) |
53+
(Sequel[:plan_spaces][:guid] =~ space_guids) |
54+
(Sequel[:broker_spaces][:guid] =~ space_guids)
55+
end
56+
end
57+
58+
def authorized_space_guids(space_guids: [], readable_space_guids: [], omniscient: false)
59+
return space_guids if omniscient
60+
61+
(Set.new(readable_space_guids) & Set.new(space_guids)).to_a
62+
end
63+
64+
def visibility_filter?(message)
65+
[:space_guids, :organization_guids].any? { |filter| message.requested?(filter) }
66+
end
67+
68+
def join_all_parent_tables(dataset)
69+
dataset.
70+
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
71+
left_join(Sequel[:spaces].as(:broker_spaces), id: Sequel[:service_brokers][:space_id]).
72+
left_join(Sequel[:organizations].as(:broker_orgs), id: Sequel[:broker_spaces][:organization_id]).
73+
left_join(:service_plan_visibilities, service_plan_id: Sequel[:service_plans][:id]).
74+
left_join(Sequel[:organizations].as(:plan_orgs), id: Sequel[:service_plan_visibilities][:organization_id]).
75+
left_join(Sequel[:spaces].as(:plan_spaces), organization_id: Sequel[:plan_orgs][:id])
76+
end
77+
end
78+
end
79+
end
Lines changed: 41 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,64 @@
1-
require 'fetchers/base_list_fetcher'
2-
require 'fetchers/label_selector_query_generator'
1+
require 'fetchers/base_service_list_fetcher'
32

43
module VCAP::CloudController
5-
class ServiceOfferingListFetcher < BaseListFetcher
4+
class ServiceOfferingListFetcher < BaseServiceListFetcher
65
class << self
7-
def fetch(message)
8-
dataset = Service.dataset.
9-
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
10-
left_join(:service_plans, service_id: Sequel[:services][:id]).
11-
left_join(:spaces, id: Sequel[:service_brokers][:space_id]).
12-
left_join(:organizations, id: Sequel[:spaces][:organization_id]).
13-
group(Sequel[:services][:id]).
14-
select_all(:services)
6+
def fetch(message, omniscient: false, readable_space_guids: [], readable_org_guids: [])
7+
dataset = Service.dataset
158

16-
dataset = filter(message, dataset)
9+
dataset = join_tables(dataset, message, omniscient)
1710

18-
return dataset unless message.requested?(:organization_guids)
11+
dataset = select_readable(
12+
dataset,
13+
omniscient: omniscient,
14+
readable_org_guids: readable_org_guids,
15+
readable_space_guids: readable_space_guids,
16+
)
1917

20-
dataset_with_visibilities(dataset, message)
21-
end
18+
if message.requested?(:space_guids)
19+
dataset = filter_spaces(
20+
dataset,
21+
filtered_space_guids: message.space_guids,
22+
readable_space_guids: readable_space_guids,
23+
omniscient: omniscient,
24+
)
25+
end
2226

23-
def fetch_public(message)
24-
dataset = Service.dataset.
25-
join(:service_plans, service_id: Sequel[:services][:id]).
26-
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
27-
left_join(:spaces, id: Sequel[:service_brokers][:space_id]).
28-
left_join(:organizations, id: Sequel[:spaces][:organization_id]).
29-
where { Sequel[:service_plans][:public] =~ true }.
30-
group(Sequel[:services][:id]).
31-
select_all(:services)
32-
33-
filter(message, dataset)
34-
end
27+
dataset = filter_orgs(dataset, message.organization_guids) if message.requested?(:organization_guids)
3528

36-
def fetch_visible(message, org_guids, space_guids)
37-
dataset = Service.dataset.
38-
left_join(:service_plans, service_id: Sequel[:services][:id]).
39-
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
40-
left_join(:spaces, id: Sequel[:service_brokers][:space_id]).
41-
left_join(:service_plan_visibilities, service_plan_id: Sequel[:service_plans][:id]).
42-
left_join(:organizations, id: Sequel[:service_plan_visibilities][:organization_id]).
43-
where do
44-
(Sequel[:organizations][:guid] =~ org_guids) |
45-
(Sequel[:service_plans][:public] =~ true) |
46-
(Sequel[:spaces][:guid] =~ space_guids)
47-
end.
48-
group(Sequel[:services][:id]).
49-
select_all(:services)
50-
51-
filter(message, dataset)
52-
end
29+
dataset = filter(message, dataset)
5330

54-
private
31+
dataset.
32+
select_all(:services).
33+
distinct
34+
end
5535

56-
def dataset_with_visibilities(dataset, message)
57-
dataset_with_visibilities = Service.dataset.
58-
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
59-
join(:service_plans, service_id: Sequel[:services][:id]).
60-
left_join(:spaces, id: Sequel[:service_brokers][:space_id]).
61-
join(:service_plan_visibilities, service_plan_id: Sequel[:service_plans][:id]).
62-
join(:organizations, id: Sequel[:service_plan_visibilities][:organization_id]).
63-
select_all(:services)
36+
def join_tables(dataset, message, omniscient)
37+
need_all_parent_tables = !omniscient || visibility_filter?(message)
6438

65-
dataset_with_visibilities = filter(message, dataset_with_visibilities)
39+
filter_properties = [
40+
:service_broker_guids,
41+
:service_broker_names,
42+
]
6643

67-
dataset.union(dataset_with_visibilities, alias: :services)
68-
end
44+
need_broker_tables = filter_properties.any? { |filter| message.requested?(filter) }
6945

70-
def filter(message, dataset)
71-
if message.requested?(:available)
72-
dataset = dataset.where(Sequel[:services][:active] =~ string_to_boolean(message.available))
46+
if need_all_parent_tables
47+
dataset = join_all_parent_tables(dataset.left_join(:service_plans, service_id: Sequel[:services][:id]))
48+
elsif need_broker_tables
49+
dataset = dataset.join(:service_brokers, id: Sequel[:services][:service_broker_id])
7350
end
7451

75-
if message.requested?(:service_broker_guids)
76-
dataset = dataset.where(Sequel[:service_brokers][:guid] =~ message.service_broker_guids)
77-
end
78-
79-
if message.requested?(:service_broker_names)
80-
dataset = dataset.where(Sequel[:service_brokers][:name] =~ message.service_broker_names)
81-
end
52+
dataset
53+
end
8254

55+
def filter(message, dataset)
8356
if message.requested?(:names)
8457
dataset = dataset.where(Sequel[:services][:label] =~ message.names)
8558
end
8659

87-
if message.requested?(:space_guids)
88-
dataset = dataset.where((Sequel[:spaces][:guid] =~ message.space_guids) | (Sequel[:service_plans][:public] =~ true))
89-
end
90-
91-
if message.requested?(:organization_guids)
92-
dataset = dataset.where((Sequel[:organizations][:guid] =~ message.organization_guids) | (Sequel[:service_plans][:public] =~ true))
60+
if message.requested?(:available)
61+
dataset = dataset.where { Sequel[:services][:active] =~ message.available? }
9362
end
9463

9564
if message.requested?(:label_selector)
@@ -103,10 +72,6 @@ def filter(message, dataset)
10372

10473
super(message, dataset, Service)
10574
end
106-
107-
def string_to_boolean(value)
108-
value == 'true'
109-
end
11075
end
11176
end
11277
end
Lines changed: 9 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
require 'set'
2-
require 'fetchers/base_list_fetcher'
3-
require 'fetchers/label_selector_query_generator'
1+
require 'fetchers/base_service_list_fetcher'
42

53
module VCAP::CloudController
6-
class ServicePlanListFetcher < BaseListFetcher
4+
class ServicePlanListFetcher < BaseServiceListFetcher
75
class << self
86
def fetch(message, omniscient: false, readable_space_guids: [], readable_org_guids: [])
97
dataset = ServicePlan.dataset
108

119
dataset = join_tables(dataset, message, omniscient)
1210

13-
dataset = select_readable_plans(
11+
dataset = select_readable(
1412
dataset,
1513
omniscient: omniscient,
1614
readable_org_guids: readable_org_guids,
@@ -28,7 +26,7 @@ def fetch(message, omniscient: false, readable_space_guids: [], readable_org_gui
2826

2927
dataset = filter_orgs(dataset, message.organization_guids) if message.requested?(:organization_guids)
3028

31-
dataset = filter(dataset, message)
29+
dataset = filter(message, dataset)
3230

3331
dataset.
3432
select_all(:service_plans).
@@ -38,7 +36,7 @@ def fetch(message, omniscient: false, readable_space_guids: [], readable_org_gui
3836
private
3937

4038
def join_tables(dataset, message, omniscient)
41-
need_all_parent_tables = !omniscient || [:space_guids, :organization_guids].any? { |filter| message.requested?(filter) }
39+
need_all_parent_tables = !omniscient || visibility_filter?(message)
4240
filter_properties = [
4341
:service_broker_guids,
4442
:service_broker_names,
@@ -50,15 +48,7 @@ def join_tables(dataset, message, omniscient)
5048
need_broker_and_offering_tables = filter_properties.any? { |filter| message.requested?(filter) }
5149

5250
if need_all_parent_tables
53-
dataset = dataset.
54-
join(:services, id: Sequel[:service_plans][:service_id]).
55-
join(:service_brokers, id: Sequel[:services][:service_broker_id]).
56-
left_join(Sequel[:spaces].as(:broker_spaces), id: Sequel[:service_brokers][:space_id]).
57-
left_join(Sequel[:organizations].as(:broker_orgs), id: Sequel[:broker_spaces][:organization_id]).
58-
left_join(:service_plan_visibilities, service_plan_id: Sequel[:service_plans][:id]).
59-
left_join(Sequel[:organizations].as(:plan_orgs), id: Sequel[:service_plan_visibilities][:organization_id]).
60-
left_join(Sequel[:spaces].as(:plan_spaces), organization_id: Sequel[:plan_orgs][:id])
61-
51+
dataset = join_all_parent_tables(dataset.join(:services, id: Sequel[:service_plans][:service_id]))
6252
elsif need_broker_and_offering_tables
6353
dataset = dataset.
6454
join(:services, id: Sequel[:service_plans][:service_id]).
@@ -72,57 +62,13 @@ def join_tables(dataset, message, omniscient)
7262
dataset
7363
end
7464

75-
def select_readable_plans(dataset, omniscient: false, readable_space_guids: [], readable_org_guids: [])
76-
if readable_org_guids.any?
77-
dataset = dataset.where do
78-
(Sequel[:service_plans][:public] =~ true) |
79-
(Sequel[:plan_orgs][:guid] =~ readable_org_guids) |
80-
(Sequel[:broker_spaces][:guid] =~ readable_space_guids)
81-
end
82-
elsif !omniscient
83-
dataset = dataset.where { Sequel[:service_plans][:public] =~ true }
84-
end
85-
86-
dataset
87-
end
88-
89-
def filter_orgs(dataset, organization_guids)
90-
dataset.where do
91-
(Sequel[:service_plans][:public] =~ true) |
92-
(Sequel[:plan_orgs][:guid] =~ organization_guids) |
93-
(Sequel[:broker_orgs][:guid] =~ organization_guids)
94-
end
95-
end
96-
97-
def filter_spaces(dataset, filtered_space_guids:, readable_space_guids:, omniscient:)
98-
space_guids = authorized_space_guids(
99-
space_guids: filtered_space_guids,
100-
readable_space_guids: readable_space_guids,
101-
omniscient: omniscient,
102-
)
103-
104-
dataset.where do
105-
(Sequel[:service_plans][:public] =~ true) |
106-
(Sequel[:plan_spaces][:guid] =~ space_guids) |
107-
(Sequel[:broker_spaces][:guid] =~ space_guids)
108-
end
109-
end
110-
111-
def filter(dataset, message)
112-
if message.requested?(:names)
113-
dataset = dataset.where { Sequel[:service_plans][:name] =~ message.names }
114-
end
115-
65+
def filter(message, dataset)
11666
if message.requested?(:available)
11767
dataset = dataset.where { Sequel[:service_plans][:active] =~ message.available? }
11868
end
11969

120-
if message.requested?(:service_broker_guids)
121-
dataset = dataset.where { Sequel[:service_brokers][:guid] =~ message.service_broker_guids }
122-
end
123-
124-
if message.requested?(:service_broker_names)
125-
dataset = dataset.where { Sequel[:service_brokers][:name] =~ message.service_broker_names }
70+
if message.requested?(:names)
71+
dataset = dataset.where { Sequel[:service_plans][:name] =~ message.names }
12672
end
12773

12874
if message.requested?(:service_offering_guids)
@@ -152,12 +98,6 @@ def filter(dataset, message)
15298

15399
super(message, dataset, ServicePlan)
154100
end
155-
156-
def authorized_space_guids(space_guids: [], readable_space_guids: [], omniscient: false)
157-
return space_guids if omniscient
158-
159-
(Set.new(readable_space_guids) & Set.new(space_guids)).to_a
160-
end
161101
end
162102
end
163103
end

app/messages/service_offerings_list_message.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,9 @@ def pagination_options
4646
end
4747
end
4848
end
49+
50+
def available?
51+
requested?(:available) && available == 'true'
52+
end
4953
end
5054
end

0 commit comments

Comments
 (0)