vcap_services_base 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|