Class: VCAP::Services::CatalogManagerV2

Inherits:
CatalogManagerBase show all
Defined in:
lib/base/catalog_manager_v2.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from CatalogManagerBase

#create_http_request

Constructor Details

#initialize(opts) ⇒ CatalogManagerV2

Returns a new instance of CatalogManagerV2.

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/base/catalog_manager_v2.rb', line 16

def initialize(opts)
  super(opts)

  @opts = opts
  @test_mode = opts[:test_mode] || false

  required_opts = %w(cloud_controller_uri token gateway_name logger).map { |o| o.to_sym }
  required_opts.concat( %w(uaa_endpoint uaa_client_id uaa_client_auth_credentials).map { |o| o.to_sym } ) if !@test_mode

  missing_opts = required_opts.select {|o| !opts.has_key? o}
  raise ArgumentError, "Missing options: #{missing_opts.join(', ')}" unless missing_opts.empty?

  @gateway_name          = opts[:gateway_name]
  @cld_ctrl_uri          = opts[:cloud_controller_uri]
  @service_list_uri      = "/v2/services?inline-relations-depth=2"

  @service_instances_uri = "/v2/service_instances"
  @service_bindings_uri  = "/v2/service_bindings"
  @handle_guid         = {}

  @logger               = opts[:logger]

  @gateway_stats = {}
  @gateway_stats_lock = Mutex.new
  snapshot_and_reset_stats
  @http_handler = HTTPHandler.new(opts)
  @multiple_page_getter = CloudControllerServices.new(
    @http_handler.method(:cc_http_request),
    @http_handler.cc_req_hdrs,
    @logger)
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



14
15
16
# File 'lib/base/catalog_manager_v2.rb', line 14

def logger
  @logger
end

Instance Method Details

#create_key(label, version, provider) ⇒ Object



48
49
50
# File 'lib/base/catalog_manager_v2.rb', line 48

def create_key(label, version, provider)
  "#{label}_#{provider}"
end

#fetch_handles_from_cc(service_label, after_fetch_callback) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/base/catalog_manager_v2.rb', line 129

def fetch_handles_from_cc(service_label, after_fetch_callback)
  logger.info("CCNG Catalog Manager:(v2) Fetching all handles from cloud controller...")
  return unless after_fetch_callback

  instance_handles = fetch_all_instance_handles_from_cc
  binding_handles = fetch_all_binding_handles_from_cc(instance_handles)
  logger.info("CCNG Catalog Manager:(v2) Successfully fetched all handles from cloud controller...")

  handles = [instance_handles, binding_handles]
  handles = VCAP::Services::Api::ListHandlesResponse.decode(Yajl::Encoder.encode({:handles => handles}))
  after_fetch_callback.call(handles) if after_fetch_callback
end

#load_registered_services_from_ccObject



125
126
127
# File 'lib/base/catalog_manager_v2.rb', line 125

def load_registered_services_from_cc
  @multiple_page_getter.load_registered_services(@service_list_uri)
end

#snapshot_and_reset_statsObject

Stats Handling #########



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/base/catalog_manager_v2.rb', line 54

def snapshot_and_reset_stats
  stats_snapshot = {}
  @gateway_stats_lock.synchronize do
    stats_snapshot = @gateway_stats.dup

    @gateway_stats[:refresh_catalog_requests]     = 0
    @gateway_stats[:refresh_catalog_failures]     = 0
    @gateway_stats[:refresh_cc_services_requests] = 0
    @gateway_stats[:refresh_cc_services_failures] = 0
    @gateway_stats[:advertise_services_requests]  = 0
    @gateway_stats[:advertise_services_failures]  = 0
  end
  stats_snapshot
end

#update_catalog(activate, catalog_loader, after_update_callback = nil) ⇒ Object

Catalog update functionality #######



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/base/catalog_manager_v2.rb', line 80

def update_catalog(activate, catalog_loader, after_update_callback = nil)
  f = Fiber.new do
    # Load offering from ccdb
    logger.info("CCNG Catalog Manager: Loading services from CC")
    failed = false
    begin
      catalog_in_ccdb = load_registered_services_from_cc

    rescue => e
      failed = true
      logger.error("CCNG Catalog Manager: Failed to get currently advertized offerings from cc: #{e.inspect}")
      logger.error(e.backtrace)
    ensure
      update_stats("refresh_cc_services", failed)
    end

    # Load current catalog (e.g. config, external marketplace etc...)
    logger.info("CCNG Catalog Manager: Loading current catalog...")
    failed = false
    begin
      current_catalog = catalog_loader.call().values.collect do |service_hash|
        label, _ = VCAP::Services::Api::Util.parse_label(service_hash.fetch('label'))
        Service.new(service_hash.merge('label' => label))
      end
    rescue => e1
      failed = true
      logger.error("CCNG Catalog Manager: Failed to get latest service catalog: #{e1.inspect}")
      logger.error(e1.backtrace)
    ensure
      update_stats("refresh_catalog", failed)
    end

    # Update
    logger.info("CCNG Catalog Manager: Updating Offerings...")
    advertise_services(current_catalog, catalog_in_ccdb, activate)

    # Post-update processing
    if after_update_callback
      logger.info("CCNG Catalog Manager: Invoking after update callback...")
      after_update_callback.call()
    end
  end
  f.resume
end

#update_handle_in_cc(service_label, handle, on_success_callback, on_failure_callback) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/base/catalog_manager_v2.rb', line 150

def update_handle_in_cc(service_label, handle, on_success_callback, on_failure_callback)
  logger.debug("CCNG Catalog Manager:(v1) Update service handle: #{handle.inspect}")
  if not handle
    on_failure_callback.call if on_failure_callback
    return
  end

  uri = update_handle_uri(handle)

  # replace the "configuration" field with "gateway_data", and remove "gateway_name" for the internal update
  handle["gateway_data"] = handle.delete("configuration")
  handle.delete("gateway_name")

  # manipulate handle to be a handle that is acceptable to ccng
  cc_handle = {
    "token"        => @service_auth_tokens.values[0],
    "credentials"  => handle["credentials"],
    "gateway_data" => handle["gateway_data"],
  }

  cc_http_request(:uri => uri,
                  :method => "put",
                  :head => @cc_req_hdrs,
                  :body => Yajl::Encoder.encode(cc_handle)) do |http|
    if ! http.error
      if http.response_header.status == 200
        logger.info("CCNG Catalog Manager:(v2) Successful update handle #{handle["service_id"]}")
        on_success_callback.call if on_success_callback
      else
        logger.error("CCNG Catalog Manager:(v2) Failed to update handle #{handle["service_id"]}: http status #{http.response_header.status}")
        on_failure_callback.call if on_failure_callback
      end
    else
      logger.error("CCNG Catalog Manager:(v2) Failed to update handle #{handle["service_id"]}: #{http.error}")
      on_failure_callback.call if on_failure_callback
    end
  end
end

#update_handle_uri(handle) ⇒ Object



142
143
144
145
146
147
148
# File 'lib/base/catalog_manager_v2.rb', line 142

def update_handle_uri(handle)
  if handle['gateway_name'] == handle['credentials']['name']
    return "#{@service_instances_uri}/internal/#{handle['gateway_name']}"
  else
    return "#{@service_bindings_uri}/internal/#{handle['gateway_name']}"
  end
end

#update_stats(op_name, failed) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/base/catalog_manager_v2.rb', line 69

def update_stats(op_name, failed)
  op_key = "#{op_name}_requests".to_sym
  op_failure_key = "#{op_name}_failures".to_sym

  @gateway_stats_lock.synchronize do
    @gateway_stats[op_key] += 1
    @gateway_stats[op_failure_key] += 1 if failed
  end
end