vcap_services_base 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/base/abstract.rb +11 -0
- data/lib/base/api/message.rb +31 -0
- data/lib/base/asynchronous_service_gateway.rb +529 -0
- data/lib/base/backup.rb +206 -0
- data/lib/base/barrier.rb +54 -0
- data/lib/base/base.rb +159 -0
- data/lib/base/base_async_gateway.rb +164 -0
- data/lib/base/base_job.rb +5 -0
- data/lib/base/catalog_manager_base.rb +67 -0
- data/lib/base/catalog_manager_v1.rb +225 -0
- data/lib/base/catalog_manager_v2.rb +291 -0
- data/lib/base/cloud_controller_services.rb +75 -0
- data/lib/base/datamapper_l.rb +148 -0
- data/lib/base/gateway.rb +167 -0
- data/lib/base/gateway_service_catalog.rb +68 -0
- data/lib/base/http_handler.rb +101 -0
- data/lib/base/job/async_job.rb +71 -0
- data/lib/base/job/config.rb +27 -0
- data/lib/base/job/lock.rb +153 -0
- data/lib/base/job/package.rb +112 -0
- data/lib/base/job/serialization.rb +365 -0
- data/lib/base/job/snapshot.rb +354 -0
- data/lib/base/node.rb +471 -0
- data/lib/base/node_bin.rb +154 -0
- data/lib/base/plan.rb +63 -0
- data/lib/base/provisioner.rb +1120 -0
- data/lib/base/provisioner_v1.rb +125 -0
- data/lib/base/provisioner_v2.rb +193 -0
- data/lib/base/service.rb +93 -0
- data/lib/base/service_advertiser.rb +184 -0
- data/lib/base/service_error.rb +122 -0
- data/lib/base/service_message.rb +94 -0
- data/lib/base/service_plan_change_set.rb +11 -0
- data/lib/base/simple_aop.rb +63 -0
- data/lib/base/snapshot_v2/snapshot.rb +227 -0
- data/lib/base/snapshot_v2/snapshot_client.rb +158 -0
- data/lib/base/snapshot_v2/snapshot_job.rb +95 -0
- data/lib/base/utils.rb +63 -0
- data/lib/base/version.rb +7 -0
- data/lib/base/warden/instance_utils.rb +161 -0
- data/lib/base/warden/node_utils.rb +205 -0
- data/lib/base/warden/service.rb +426 -0
- data/lib/base/worker_bin.rb +76 -0
- data/lib/vcap_services_base.rb +16 -0
- metadata +364 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'abstract'
|
2
|
+
|
3
|
+
module VCAP
|
4
|
+
module Services
|
5
|
+
class CatalogManagerBase
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
@proxy_opts = opts[:proxy]
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_http_request(args)
|
12
|
+
req = {
|
13
|
+
:head => args[:head],
|
14
|
+
:body => args[:body],
|
15
|
+
}
|
16
|
+
if (@proxy_opts)
|
17
|
+
req[:proxy] = @proxy_opts
|
18
|
+
# this is a workaround for em-http-requesr 0.3.0 so that headers are not lost
|
19
|
+
# more info: https://github.com/igrigorik/em-http-request/issues/130
|
20
|
+
req[:proxy][:head] = req[:head]
|
21
|
+
end
|
22
|
+
|
23
|
+
f = Fiber.current
|
24
|
+
http = EM::HttpRequest.new(args[:uri]).send(args[:method], req)
|
25
|
+
if http.error && http.error != ""
|
26
|
+
unless args[:need_raise]
|
27
|
+
@logger.error("CC Catalog Manager: Failed to connect to CC, the error is #{http.error}")
|
28
|
+
return
|
29
|
+
else
|
30
|
+
raise("CC Catalog Manager: Failed to connect to CC, the error is #{http.error}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
http.callback { f.resume(http, nil) }
|
34
|
+
http.errback { |e| f.resume(http, e) }
|
35
|
+
_, error = Fiber.yield
|
36
|
+
yield http, error if block_given?
|
37
|
+
http
|
38
|
+
end
|
39
|
+
|
40
|
+
abstract :snapshot_and_reset_stats
|
41
|
+
|
42
|
+
# update_catalog(activate, load_catalog_callback, after_update_callback=nil)
|
43
|
+
abstract :update_catalog
|
44
|
+
|
45
|
+
# generate_cc_advertise_offering_request(svc, active = true)
|
46
|
+
abstract :generate_cc_advertise_offering_request
|
47
|
+
|
48
|
+
# advertise_service_to_cc(svc, active)
|
49
|
+
abstract :advertise_service_to_cc
|
50
|
+
|
51
|
+
# load_registered_services_from_cc
|
52
|
+
abstract :load_registered_services_from_cc
|
53
|
+
|
54
|
+
# delete_offering(id, version, provider)
|
55
|
+
abstract :delete_offering
|
56
|
+
|
57
|
+
##### Handles processing #####
|
58
|
+
|
59
|
+
# update_handle_in_cc(service_label, handle, on_success_callback, on_failure_callback)
|
60
|
+
abstract :update_handle_in_cc
|
61
|
+
|
62
|
+
# fetch_handles_from_cc(service_label, after_fetch_callback)
|
63
|
+
abstract :fetch_handles_from_cc
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
require 'nats/client'
|
3
|
+
require 'uri'
|
4
|
+
require 'catalog_manager_base'
|
5
|
+
|
6
|
+
module VCAP
|
7
|
+
module Services
|
8
|
+
class CatalogManagerV1 < VCAP::Services::CatalogManagerBase
|
9
|
+
|
10
|
+
REQ_OPTS = %w(cloud_controller_uri token gateway_name logger).map {|o| o.to_sym}
|
11
|
+
|
12
|
+
def initialize(opts)
|
13
|
+
super(opts)
|
14
|
+
|
15
|
+
missing_opts = REQ_OPTS.select {|o| !opts.has_key? o}
|
16
|
+
raise ArgumentError, "Missing options: #{missing_opts.join(', ')}" unless missing_opts.empty?
|
17
|
+
|
18
|
+
@gateway_name = opts[:gateway_name]
|
19
|
+
|
20
|
+
@cld_ctrl_uri = opts[:cloud_controller_uri]
|
21
|
+
@service_list_uri = "#{@cld_ctrl_uri}/proxied_services/v1/offerings"
|
22
|
+
@offering_uri = "#{@cld_ctrl_uri}/services/v1/offerings"
|
23
|
+
@logger = opts[:logger]
|
24
|
+
|
25
|
+
token_hdrs = VCAP::Services::Api::GATEWAY_TOKEN_HEADER
|
26
|
+
@cc_req_hdrs = {
|
27
|
+
'Content-Type' => 'application/json',
|
28
|
+
token_hdrs => opts[:token],
|
29
|
+
}
|
30
|
+
|
31
|
+
@gateway_stats = {}
|
32
|
+
@gateway_stats_lock = Mutex.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def snapshot_and_reset_stats
|
36
|
+
stats_snapshot = {}
|
37
|
+
@gateway_stats_lock.synchronize do
|
38
|
+
stats_snapshot = @gateway_stats.dup
|
39
|
+
end
|
40
|
+
stats_snapshot
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_handles_uri(service_label)
|
44
|
+
"#{@cld_ctrl_uri}/services/v1/offerings/#{service_label}/handles"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_key(label, version, provider)
|
48
|
+
"#{label}-#{version}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_catalog(activate, load_catalog_callback, after_update_callback = nil)
|
52
|
+
f = Fiber.new do
|
53
|
+
configured_services = load_catalog_callback.call()
|
54
|
+
active_count = 0
|
55
|
+
configured_services.values.each { |svc|
|
56
|
+
advertise_service_to_cc(svc, activate)
|
57
|
+
active_count += 1 if activate
|
58
|
+
}
|
59
|
+
|
60
|
+
@gateway_stats_lock.synchronize do
|
61
|
+
@gateway_stats[:active_offerings] = active_count
|
62
|
+
end
|
63
|
+
|
64
|
+
after_update_callback.call if after_update_callback
|
65
|
+
end
|
66
|
+
f.resume
|
67
|
+
end
|
68
|
+
|
69
|
+
def generate_cc_advertise_offering_request(svc, active = true)
|
70
|
+
plans = svc["plans"] if svc["plans"].is_a?(Array)
|
71
|
+
if svc["plans"].is_a?(Hash)
|
72
|
+
plans = []
|
73
|
+
svc["plans"].keys.each { |k| plans << k.to_s }
|
74
|
+
end
|
75
|
+
|
76
|
+
VCAP::Services::Api::ServiceOfferingRequest.new({
|
77
|
+
:label => svc["label"],
|
78
|
+
:description => svc["description"],
|
79
|
+
|
80
|
+
:provider => svc["provider"] || 'core',
|
81
|
+
|
82
|
+
:url => svc["url"],
|
83
|
+
|
84
|
+
:plans => plans,
|
85
|
+
:cf_plan_id => svc["cf_plan_id"],
|
86
|
+
:default_plan => svc["default_plan"],
|
87
|
+
|
88
|
+
:tags => svc["tags"] || [],
|
89
|
+
|
90
|
+
:active => active,
|
91
|
+
|
92
|
+
:acls => svc["acls"],
|
93
|
+
|
94
|
+
:supported_versions => svc["supported_versions"],
|
95
|
+
:version_aliases => svc["version_aliases"],
|
96
|
+
|
97
|
+
:timeout => svc["timeout"],
|
98
|
+
}).encode
|
99
|
+
end
|
100
|
+
|
101
|
+
def load_registered_services_from_cc
|
102
|
+
@logger.info("CC Catalog Manager: Get registred services from cloud_controller: #{@service_list_uri}")
|
103
|
+
|
104
|
+
services = {}
|
105
|
+
create_http_request(:uri => @service_list_uri, :method => "get", :head => @cc_req_hdrs, :need_raise => true) do |http, error|
|
106
|
+
if !error
|
107
|
+
if http.response_header.status == 200
|
108
|
+
resp = JSON.parse(http.response)
|
109
|
+
resp["proxied_services"].each {|svc|
|
110
|
+
@logger.info("CC Catalog Manager: Fetch #{@gateway_name} service from CC: label=#{svc["label"]} - #{svc.inspect}")
|
111
|
+
services[svc["label"]] = svc
|
112
|
+
}
|
113
|
+
else
|
114
|
+
raise "CC Catalog Manager: Failed to fetch #{@gateway_name} service from CC - status=#{http.response_header.status}"
|
115
|
+
end
|
116
|
+
else
|
117
|
+
raise "CC Catalog Manager: Failed to fetch #{@gateway_name} service from CC: #{http.error}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
return services
|
122
|
+
end
|
123
|
+
|
124
|
+
def advertise_service_to_cc(svc, active = true)
|
125
|
+
offering = generate_cc_advertise_offering_request(svc, active)
|
126
|
+
|
127
|
+
@logger.debug("CC Catalog Manager: Advertise service offering #{offering.inspect} to cloud_controller: #{@offering_uri}")
|
128
|
+
return false unless offering
|
129
|
+
|
130
|
+
create_http_request(:uri => @offering_uri, :method => "post", :head => @cc_req_hdrs, :body => offering) do |http, error|
|
131
|
+
if !error
|
132
|
+
if http.response_header.status == 200
|
133
|
+
@logger.info("CC Catalog Manager: Successfully advertised offering: #{offering.inspect}")
|
134
|
+
return true
|
135
|
+
else
|
136
|
+
@logger.error("CC Catalog Manager: Failed to advertise offerings:#{offering.inspect}, status=#{http.response_header.status}")
|
137
|
+
end
|
138
|
+
else
|
139
|
+
@logger.error("CC Catalog Manager: Failed to advertise offerings:#{offering.inspect}: #{http.error}")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
|
145
|
+
def delete_offering(id, version, provider)
|
146
|
+
# See: https://github.com/cloudfoundry/cloud_controller/blob/master/cloud_controller/config/routes.rb
|
147
|
+
offering_id = "#{id}-#{version}/#{provider}"
|
148
|
+
uri = "#{@offering_uri}/#{offering_id}"
|
149
|
+
@logger.info("CC Catalog Manager: Delete service offering: #{offering_id}")
|
150
|
+
|
151
|
+
create_http_request(:uri => uri, :method => "delete", :head => @cc_req_hdrs) do |http, error|
|
152
|
+
if !error
|
153
|
+
if http.response_header.status == 200
|
154
|
+
@logger.info("CC Catalog Manager: Successfully deleted offering: #{offering_id}")
|
155
|
+
return true
|
156
|
+
else
|
157
|
+
@logger.warn("CC Catalog Manager: Failed to delete offering: #{offering_id}, status: #{http.response_header.status}")
|
158
|
+
end
|
159
|
+
else
|
160
|
+
@logger.warn("CC Catalog Manager: Failed to delete offering: #{offering_id} due to: #{http.error}")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
return false
|
164
|
+
end
|
165
|
+
|
166
|
+
###### Handles processing #####
|
167
|
+
|
168
|
+
def fetch_handles_from_cc(service_label, after_fetch_callback)
|
169
|
+
return if @fetching_handles
|
170
|
+
|
171
|
+
handles_uri = get_handles_uri(service_label)
|
172
|
+
|
173
|
+
@logger.info("CC Catalog Manager: Fetching handles from cloud controller: #{handles_uri}")
|
174
|
+
@fetching_handles = true
|
175
|
+
|
176
|
+
create_http_request(:uri => handles_uri, :method => "get", :head => @cc_req_hdrs) do |http, error|
|
177
|
+
@fetching_handles = false
|
178
|
+
|
179
|
+
if !error
|
180
|
+
if http.response_header.status == 200
|
181
|
+
@logger.info("CC Catalog Manager: Successfully fetched handles")
|
182
|
+
|
183
|
+
begin
|
184
|
+
resp = VCAP::Services::Api::ListHandlesResponse.decode(http.response)
|
185
|
+
after_fetch_callback.call(resp) if after_fetch_callback
|
186
|
+
rescue => e
|
187
|
+
@logger.error("CC Catalog Manager: Error decoding reply from gateway: #{e}")
|
188
|
+
end
|
189
|
+
else
|
190
|
+
@logger.error("CC Catalog Manager: Failed fetching handles, status=#{http.response_header.status}")
|
191
|
+
end
|
192
|
+
else
|
193
|
+
@logger.error("CC Catalog Manager: Failed fetching handles: #{http.error}")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def update_handle_in_cc(service_label, handle, on_success_callback, on_failure_callback)
|
199
|
+
@logger.debug("CC Catalog Manager: Update service handle: #{handle.inspect}")
|
200
|
+
if not handle
|
201
|
+
on_failure_callback.call if on_failure_callback
|
202
|
+
return
|
203
|
+
end
|
204
|
+
|
205
|
+
uri = "#{get_handles_uri(service_label)}/#{handle["service_id"]}"
|
206
|
+
|
207
|
+
create_http_request(:uri => uri, method => "post", :head => @cc_req_hdrs, :body => Yajl::Encoder.encode(handle)) do |http, error|
|
208
|
+
if !error
|
209
|
+
if http.response_header.status == 200
|
210
|
+
@logger.info("CC Catalog Manager: Successful update handle #{handle["service_id"]}")
|
211
|
+
on_success_callback.call if on_success_callback
|
212
|
+
else
|
213
|
+
@logger.error("CC Catalog Manager: Failed to update handle #{handle["service_id"]}: http status #{http.response_header.status}")
|
214
|
+
on_failure_callback.call if on_failure_callback
|
215
|
+
end
|
216
|
+
else
|
217
|
+
@logger.error("CC Catalog Manager: Failed to update handle #{handle["service_id"]}: #{http.error}")
|
218
|
+
on_failure_callback.call if on_failure_callback
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
require 'nats/client'
|
3
|
+
require 'uri'
|
4
|
+
require 'uaa'
|
5
|
+
require 'services/api/const'
|
6
|
+
require 'catalog_manager_base'
|
7
|
+
require 'base/cloud_controller_services'
|
8
|
+
require 'base/http_handler'
|
9
|
+
require 'base/service_advertiser'
|
10
|
+
|
11
|
+
module VCAP
|
12
|
+
module Services
|
13
|
+
class CatalogManagerV2 < VCAP::Services::CatalogManagerBase
|
14
|
+
attr_reader :logger
|
15
|
+
|
16
|
+
def initialize(opts)
|
17
|
+
super(opts)
|
18
|
+
|
19
|
+
@opts = opts
|
20
|
+
@test_mode = opts[:test_mode] || false
|
21
|
+
|
22
|
+
required_opts = %w(cloud_controller_uri token gateway_name logger).map { |o| o.to_sym }
|
23
|
+
required_opts.concat( %w(uaa_endpoint uaa_client_id uaa_client_auth_credentials).map { |o| o.to_sym } ) if !@test_mode
|
24
|
+
|
25
|
+
missing_opts = required_opts.select {|o| !opts.has_key? o}
|
26
|
+
raise ArgumentError, "Missing options: #{missing_opts.join(', ')}" unless missing_opts.empty?
|
27
|
+
|
28
|
+
@gateway_name = opts[:gateway_name]
|
29
|
+
@cld_ctrl_uri = opts[:cloud_controller_uri]
|
30
|
+
@service_list_uri = "/v2/services?inline-relations-depth=2"
|
31
|
+
|
32
|
+
@service_instances_uri = "/v2/service_instances"
|
33
|
+
@service_bindings_uri = "/v2/service_bindings"
|
34
|
+
@handle_guid = {}
|
35
|
+
|
36
|
+
@logger = opts[:logger]
|
37
|
+
|
38
|
+
@gateway_stats = {}
|
39
|
+
@gateway_stats_lock = Mutex.new
|
40
|
+
snapshot_and_reset_stats
|
41
|
+
@http_handler = HTTPHandler.new(opts)
|
42
|
+
@multiple_page_getter = CloudControllerServices.new(
|
43
|
+
@http_handler.method(:cc_http_request),
|
44
|
+
@http_handler.cc_req_hdrs,
|
45
|
+
@logger)
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_key(label, version, provider)
|
49
|
+
"#{label}_#{provider}"
|
50
|
+
end
|
51
|
+
|
52
|
+
######### Stats Handling #########
|
53
|
+
|
54
|
+
def snapshot_and_reset_stats
|
55
|
+
stats_snapshot = {}
|
56
|
+
@gateway_stats_lock.synchronize do
|
57
|
+
stats_snapshot = @gateway_stats.dup
|
58
|
+
|
59
|
+
@gateway_stats[:refresh_catalog_requests] = 0
|
60
|
+
@gateway_stats[:refresh_catalog_failures] = 0
|
61
|
+
@gateway_stats[:refresh_cc_services_requests] = 0
|
62
|
+
@gateway_stats[:refresh_cc_services_failures] = 0
|
63
|
+
@gateway_stats[:advertise_services_requests] = 0
|
64
|
+
@gateway_stats[:advertise_services_failures] = 0
|
65
|
+
end
|
66
|
+
stats_snapshot
|
67
|
+
end
|
68
|
+
|
69
|
+
def update_stats(op_name, failed)
|
70
|
+
op_key = "#{op_name}_requests".to_sym
|
71
|
+
op_failure_key = "#{op_name}_failures".to_sym
|
72
|
+
|
73
|
+
@gateway_stats_lock.synchronize do
|
74
|
+
@gateway_stats[op_key] += 1
|
75
|
+
@gateway_stats[op_failure_key] += 1 if failed
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
######### Catalog update functionality #######
|
80
|
+
def update_catalog(activate, catalog_loader, after_update_callback = nil)
|
81
|
+
f = Fiber.new do
|
82
|
+
# Load offering from ccdb
|
83
|
+
logger.info("CCNG Catalog Manager: Loading services from CC")
|
84
|
+
failed = false
|
85
|
+
begin
|
86
|
+
catalog_in_ccdb = load_registered_services_from_cc
|
87
|
+
|
88
|
+
rescue => e
|
89
|
+
failed = true
|
90
|
+
logger.error("CCNG Catalog Manager: Failed to get currently advertized offerings from cc: #{e.inspect}")
|
91
|
+
logger.error(e.backtrace)
|
92
|
+
ensure
|
93
|
+
update_stats("refresh_cc_services", failed)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Load current catalog (e.g. config, external marketplace etc...)
|
97
|
+
logger.info("CCNG Catalog Manager: Loading current catalog...")
|
98
|
+
failed = false
|
99
|
+
begin
|
100
|
+
current_catalog = catalog_loader.call().values.collect do |service_hash|
|
101
|
+
label, _ = VCAP::Services::Api::Util.parse_label(service_hash.fetch('label'))
|
102
|
+
Service.new(service_hash.merge('label' => label))
|
103
|
+
end
|
104
|
+
rescue => e1
|
105
|
+
failed = true
|
106
|
+
logger.error("CCNG Catalog Manager: Failed to get latest service catalog: #{e1.inspect}")
|
107
|
+
logger.error(e1.backtrace)
|
108
|
+
ensure
|
109
|
+
update_stats("refresh_catalog", failed)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Update
|
113
|
+
logger.info("CCNG Catalog Manager: Updating Offerings...")
|
114
|
+
advertise_services(current_catalog, catalog_in_ccdb, activate)
|
115
|
+
|
116
|
+
# Post-update processing
|
117
|
+
if after_update_callback
|
118
|
+
logger.info("CCNG Catalog Manager: Invoking after update callback...")
|
119
|
+
after_update_callback.call()
|
120
|
+
end
|
121
|
+
end
|
122
|
+
f.resume
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_registered_services_from_cc
|
126
|
+
@multiple_page_getter.load_registered_services(@service_list_uri)
|
127
|
+
end
|
128
|
+
|
129
|
+
def fetch_handles_from_cc(service_label, after_fetch_callback)
|
130
|
+
logger.info("CCNG Catalog Manager:(v2) Fetching all handles from cloud controller...")
|
131
|
+
return unless after_fetch_callback
|
132
|
+
|
133
|
+
instance_handles = fetch_all_instance_handles_from_cc
|
134
|
+
binding_handles = fetch_all_binding_handles_from_cc(instance_handles)
|
135
|
+
logger.info("CCNG Catalog Manager:(v2) Successfully fetched all handles from cloud controller...")
|
136
|
+
|
137
|
+
handles = [instance_handles, binding_handles]
|
138
|
+
handles = VCAP::Services::Api::ListHandlesResponse.decode(Yajl::Encoder.encode({:handles => handles}))
|
139
|
+
after_fetch_callback.call(handles) if after_fetch_callback
|
140
|
+
end
|
141
|
+
|
142
|
+
def update_handle_uri(handle)
|
143
|
+
if handle['gateway_name'] == handle['credentials']['name']
|
144
|
+
return "#{@service_instances_uri}/internal/#{handle['gateway_name']}"
|
145
|
+
else
|
146
|
+
return "#{@service_bindings_uri}/internal/#{handle['gateway_name']}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def update_handle_in_cc(service_label, handle, on_success_callback, on_failure_callback)
|
151
|
+
logger.debug("CCNG Catalog Manager:(v1) Update service handle: #{handle.inspect}")
|
152
|
+
if not handle
|
153
|
+
on_failure_callback.call if on_failure_callback
|
154
|
+
return
|
155
|
+
end
|
156
|
+
|
157
|
+
uri = update_handle_uri(handle)
|
158
|
+
|
159
|
+
# replace the "configuration" field with "gateway_data", and remove "gateway_name" for the internal update
|
160
|
+
handle["gateway_data"] = handle.delete("configuration")
|
161
|
+
handle.delete("gateway_name")
|
162
|
+
|
163
|
+
# manipulate handle to be a handle that is acceptable to ccng
|
164
|
+
cc_handle = {
|
165
|
+
"token" => @service_auth_tokens.values[0],
|
166
|
+
"credentials" => handle["credentials"],
|
167
|
+
"gateway_data" => handle["gateway_data"],
|
168
|
+
}
|
169
|
+
|
170
|
+
cc_http_request(:uri => uri,
|
171
|
+
:method => "put",
|
172
|
+
:head => @cc_req_hdrs,
|
173
|
+
:body => Yajl::Encoder.encode(cc_handle)) do |http|
|
174
|
+
if ! http.error
|
175
|
+
if http.response_header.status == 200
|
176
|
+
logger.info("CCNG Catalog Manager:(v2) Successful update handle #{handle["service_id"]}")
|
177
|
+
on_success_callback.call if on_success_callback
|
178
|
+
else
|
179
|
+
logger.error("CCNG Catalog Manager:(v2) Failed to update handle #{handle["service_id"]}: http status #{http.response_header.status}")
|
180
|
+
on_failure_callback.call if on_failure_callback
|
181
|
+
end
|
182
|
+
else
|
183
|
+
logger.error("CCNG Catalog Manager:(v2) Failed to update handle #{handle["service_id"]}: #{http.error}")
|
184
|
+
on_failure_callback.call if on_failure_callback
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
def fetch_all_instance_handles_from_cc
|
191
|
+
logger.info("CCNG Catalog Manager:(v2) Fetching all service instance handles from cloud controller: #{@cld_ctrl_uri}#{@service_instance_uri}")
|
192
|
+
instance_handle_list = {}
|
193
|
+
|
194
|
+
registered_services = load_registered_services_from_cc
|
195
|
+
|
196
|
+
registered_services.each do |registered_service|
|
197
|
+
registered_service.plans.each do |plan_details|
|
198
|
+
plan_guid = plan_details.guid
|
199
|
+
instance_handles_query = "?q=service_plan_guid:#{plan_guid}"
|
200
|
+
instance_handles = fetch_instance_handles_from_cc(instance_handles_query)
|
201
|
+
instance_handle_list.merge!(instance_handles) if instance_handles
|
202
|
+
end
|
203
|
+
end
|
204
|
+
logger.info("CCNG Catalog Manager:(v2) Successfully fetched all service instance handles from cloud controller: #{@cld_ctrl_uri}#{@service_instance_uri}")
|
205
|
+
instance_handle_list
|
206
|
+
end
|
207
|
+
|
208
|
+
# fetch instance handles from cloud_controller_ng
|
209
|
+
# this function allows users to get a dedicated set of instance handles
|
210
|
+
# from cloud_controller_ng using a customized query for /v2/service_binding api
|
211
|
+
#
|
212
|
+
# @param string instance_handles_query
|
213
|
+
def fetch_instance_handles_from_cc(instance_handles_query)
|
214
|
+
logger.info("CCNG Catalog Manager:(v2) Fetching service instance handles from cloud controller: #{@cld_ctrl_uri}#{@service_instance_uri}#{instance_handles_query}")
|
215
|
+
|
216
|
+
instance_handles = {}
|
217
|
+
# currently we are fetching all the service instances from different plans;
|
218
|
+
# TODO: add a query parameter in ccng v2 to support a query from service name to instance handle;
|
219
|
+
service_instance_uri = "#{@service_instances_uri}#{instance_handles_query}"
|
220
|
+
|
221
|
+
@multiple_page_getter.each(service_instance_uri, "service instance handles") do |resources|
|
222
|
+
instance_info = resources['entity']
|
223
|
+
instance_handles[instance_info['credentials']['name']] = instance_info
|
224
|
+
@handle_guid[instance_info['credentials']['name']] = resources['metadata']['guid']
|
225
|
+
end
|
226
|
+
instance_handles
|
227
|
+
rescue => e
|
228
|
+
logger.error("CCNG Catalog Manager:(v2) Error decoding reply from gateway: #{e.backtrace}")
|
229
|
+
end
|
230
|
+
|
231
|
+
def fetch_all_binding_handles_from_cc(instance_handles)
|
232
|
+
logger.info("CCNG Catalog Manager:(v2) Fetching all service binding handles from cloud controller: #{@cld_ctrl_uri}#{@service_instance_uri}")
|
233
|
+
binding_handles_list = {}
|
234
|
+
|
235
|
+
# currently we will fetch each binding handle according to instance handle
|
236
|
+
# TODO: add a query parameter in ccng v2 to support query from service name to binding handle;
|
237
|
+
instance_handles.each do |instance_id, _|
|
238
|
+
binding_handles_query = "?q=service_instance_guid:#{@handle_guid[instance_id]}"
|
239
|
+
binding_handles = fetch_binding_handles_from_cc(binding_handles_query)
|
240
|
+
binding_handles_list.merge!(binding_handles) if binding_handles
|
241
|
+
end
|
242
|
+
logger.info("CCNG Catalog Manager:(v2) Successfully fetched all service binding handles from cloud controller: #{@cld_ctrl_uri}#{@service_instance_uri}")
|
243
|
+
binding_handles_list
|
244
|
+
end
|
245
|
+
|
246
|
+
# fetch binding handles from cloud_controller_ng
|
247
|
+
# this function allows users to get a dedicated set of binding handles
|
248
|
+
# from cloud_controller_ng using a customized query for /v2/service_binding api
|
249
|
+
#
|
250
|
+
# @param string binding_handles_query
|
251
|
+
def fetch_binding_handles_from_cc(binding_handles_query)
|
252
|
+
logger.info("CCNG Catalog Manager:(v2) Fetching service binding handles from cloud controller: #{@cld_ctrl_uri}#{@service_bindings_uri}#{binding_handles_query}")
|
253
|
+
|
254
|
+
binding_handles = {}
|
255
|
+
binding_handles_uri = "#{@service_bindings_uri}#{binding_handles_query}"
|
256
|
+
|
257
|
+
@multiple_page_getter.each(binding_handles_uri, "service binding handles") do |resources|
|
258
|
+
binding_info = resources['entity']
|
259
|
+
binding_handles[binding_info['gateway_name']] = binding_info
|
260
|
+
@handle_guid[binding_info['gateway_name']] = resources['metadata']['guid']
|
261
|
+
end
|
262
|
+
binding_handles
|
263
|
+
rescue => e
|
264
|
+
logger.error("CCNG Catalog Manager:(v2) Error decoding reply from gateway: #{e}")
|
265
|
+
end
|
266
|
+
|
267
|
+
def advertise_services(current_catalog, catalog_in_ccdb, active=true)
|
268
|
+
logger.info("CCNG Catalog Manager: #{active ? "Activate" : "Deactivate"} services...")
|
269
|
+
|
270
|
+
if !(current_catalog && catalog_in_ccdb)
|
271
|
+
logger.warn("CCNG Catalog Manager: Cannot advertise services since the offerings list from either the catalog or ccdb could not be retrieved")
|
272
|
+
return
|
273
|
+
end
|
274
|
+
|
275
|
+
service_advertiser = ServiceAdvertiser.new(
|
276
|
+
current_catalog: current_catalog,
|
277
|
+
catalog_in_ccdb: catalog_in_ccdb,
|
278
|
+
http_handler: @http_handler,
|
279
|
+
logger: logger,
|
280
|
+
active: active
|
281
|
+
)
|
282
|
+
service_advertiser.advertise_services
|
283
|
+
|
284
|
+
@gateway_stats_lock.synchronize do
|
285
|
+
@gateway_stats[:active_offerings] = service_advertiser.active_count
|
286
|
+
@gateway_stats[:disabled_services] = service_advertiser.disabled_count
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|