Skip to content

Commit bd76f71

Browse files
sethboylestcdowney
andcommitted
Speed up v5 syslog_drain_urls
This commit adds a cache for credentials for user-provided-services (since we know they are guaranteed to share the same creds, unlike managed) Co-authored-by: Seth Boyles <[email protected]> Co-authored-by: Tim Downey <[email protected]>
1 parent df3184f commit bd76f71

File tree

2 files changed

+305
-243
lines changed

2 files changed

+305
-243
lines changed

app/controllers/internal/syslog_drain_urls_controller.rb

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'oj'
2+
13
module VCAP::CloudController
24
class SyslogDrainUrlsInternalController < RestController::BaseController
35
# Endpoint uses mutual tls for auth, handled by nginx
@@ -55,32 +57,35 @@ def listv5
5557
join(:apps, guid: :app_guid).
5658
join(:spaces, guid: :apps__space_guid).
5759
join(:organizations, id: :spaces__organization_id).
60+
join(:service_instances, guid: :service_bindings__service_instance_guid).
5861
select(
5962
:service_bindings__syslog_drain_url,
6063
:service_bindings__credentials,
6164
:service_bindings__salt,
6265
:service_bindings__encryption_key_label,
6366
:service_bindings__encryption_iterations,
6467
:service_bindings__app_guid,
68+
:service_bindings__service_instance_guid,
6569
:apps__name___app_name,
6670
:spaces__name___space_name,
67-
:organizations__name___organization_name
71+
:organizations__name___organization_name,
72+
:service_instances__is_gateway_service___is_managed_service
6873
).
6974
where(service_bindings__syslog_drain_url: syslog_drain_urls_query).
7075

7176
each_with_object({}) do |item, injected|
7277
syslog_drain_url = item[:syslog_drain_url]
73-
credentials = item.credentials
74-
cert = credentials&.fetch('cert', '') || ''
75-
key = credentials&.fetch('key', '') || ''
76-
ca = credentials&.fetch('ca', '') || ''
78+
7779
hostname = hostname_from_app_name(item[:organization_name], item[:space_name], item[:app_name])
7880
app_guid = item[:app_guid]
7981

82+
cert, key, ca = fetch_credentials_from_cache(item)
83+
8084
injected_item = injected[syslog_drain_url] ||= {
8185
url: syslog_drain_url,
8286
binding_data_map: {}
8387
}
88+
8489
cert_item = injected_item[:binding_data_map][[key, cert, ca]] ||= {
8590
cert: cert,
8691
key: key,
@@ -99,11 +104,45 @@ def listv5
99104

100105
next_page_token = nil
101106
next_page_token = last_id + batch_size unless bindings.empty?
102-
[HTTP::OK, MultiJson.dump({ results: bindings, next_id: next_page_token }, pretty: true)]
107+
[HTTP::OK, Oj.dump({ results: bindings, next_id: next_page_token })]
103108
end
104109

105110
private
106111

112+
def upsi_service_instance_credential_cache
113+
@upsi_service_instance_credential_cache ||= {}
114+
end
115+
116+
# Service Binding credentials are stored as encrypted values in CCDB.
117+
# Decrypting them is computationally expensive and has caused performance
118+
# issues since this endpoint may decrypt credentials from thousands of service bindings.
119+
#
120+
# Since all user-provided service instance bindings share the same credentials
121+
# as their service instance we can safely cache the for a given service instance guid.
122+
def fetch_credentials_from_cache(item)
123+
if item[:is_managed_service]
124+
credentials = item.credentials
125+
cert = credentials&.fetch('cert', '') || ''
126+
key = credentials&.fetch('key', '') || ''
127+
ca = credentials&.fetch('ca', '') || ''
128+
else # service is user-provided
129+
upsi_service_instance_credential_cache[item.service_instance_guid] ||= {}
130+
131+
if upsi_service_instance_credential_cache[item.service_instance_guid].empty?
132+
credentials = item.credentials
133+
upsi_service_instance_credential_cache[item.service_instance_guid]['cert'] = credentials&.fetch('cert', '') || ''
134+
upsi_service_instance_credential_cache[item.service_instance_guid]['key'] = credentials&.fetch('key', '') || ''
135+
upsi_service_instance_credential_cache[item.service_instance_guid]['ca'] = credentials&.fetch('ca', '') || ''
136+
end
137+
138+
cert = upsi_service_instance_credential_cache[item.service_instance_guid].fetch('cert', '')
139+
key = upsi_service_instance_credential_cache[item.service_instance_guid].fetch('key', '')
140+
ca = upsi_service_instance_credential_cache[item.service_instance_guid].fetch('ca', '')
141+
end
142+
143+
[cert, key, ca]
144+
end
145+
107146
def syslog_drain_urls_query
108147
ServiceBinding.
109148
distinct.

0 commit comments

Comments
 (0)