Skip to content
Browse files

NATS integration

  This change adds the following message bus behaviors:
  - Component announcement / registration
  - router registration and re-registration
  Also included is a patch addressing the incompatibility introduced by
Yajl's JSON gem ``compatibility'' layer. Ironies abound.

  Test plan:
  - Unit tests passed
  - Deploy to dev instance and ad-hock test http end points on both the
    CCNG domain and API2 domain.

Change-Id: Icc1038e990523065883b4c281920da4b2668f03d
  • Loading branch information...
1 parent 0a5048f commit 4edadbb99fcee36b24dd67c60def86bbca643af4 @d d committed Jul 6, 2012
View
2 config/cloud_controller.yml
@@ -3,6 +3,8 @@ port: 8181
pid_filename: /tmp/cloud_controller.pid
nats_uri: nats://127.0.0.1:4222
+external_domain: api2.vcap.me
+
bootstrap_admin_email: sre@vmware.com
info:
View
1 lib/cloud_controller/config.rb
@@ -76,6 +76,7 @@ def self.configure(config)
# TODO: this introduces 2 config styles. CC takes config
# via per instance constructor. Remove that in favor of this
# method as there will be more along these lines.
+ VCAP::CloudController::MessageBus.configure(config)
VCAP::CloudController::RestController::QuotaManager.configure(config)
VCAP::CloudController::Models::AccountCapacity.configure(config)
end
View
12 lib/cloud_controller/json_patch.rb
@@ -0,0 +1,12 @@
+# Copyright (c) 2012-2012 VMware, Inc.
+
+# FIXME: this is so gross
+# Monkey-patching the monkeypatch: UAA gem is unhappy because yajl/json_gem
+# ignores symbolize_names
+# The UAA client gem should probably move to Yajl...
+def JSON.parse(str, opts=JSON.default_options)
+ if opts.delete(:symbolize_names)
+ opts[:symbolize_keys] = true
+ end
+ Yajl::Parser.parse(str, opts)
+end
View
52 lib/cloud_controller/message_bus.rb
@@ -0,0 +1,52 @@
+# Copyright (c) 2012-2012 VMware, Inc.
+
+require "nats/client"
+require "vcap/component"
+require "cloud_controller/json_patch"
+
+module VCAP::CloudController::MessageBus
+ class << self
+ attr_reader :config
+ attr_reader :nats
+
+ def configure(config)
+ @config = config
+ @nats = config[:nats] || NATS
+ end
+ end
+
+ def self.register_components
+ # hook up with NATS
+ # TODO: put useful metrics in varz
+ # TODO: subscribe to the two DEA channels
+ EM.schedule do
+ nats.start(:uri => config[:nats_uri]) do
+ VCAP::Component.register(
+ :type => 'CloudController',
+ :host => VCAP.local_ip,
+ :index => config[:index],
+ :config => config,
+ # leaving the varz port / user / pwd blank to be random
+ )
+ end
+ end
+ end
+
+ def self.register_routes
+ EM.schedule do
+ # TODO: blacklist api2 in legacy CC
+ # TODO: Yajl should probably also be injected
+ router_register_message = Yajl::Encoder.encode({
+ :host => VCAP.local_ip,
+ :port => config[:port],
+ :uris => [config[:external_domain]],
+ :tags => {:component => "CloudController" },
+ })
+ nats.publish("router.register", router_register_message)
+ # Broadcast when a router restarts
+ nats.subscribe("router.start") do
+ nats.publish("router.register", router_register_message)
+ end
+ end
+ end
+end
View
20 lib/cloud_controller/runner.rb
@@ -1,4 +1,5 @@
# Copyright (c) 2009-2012 VMware, Inc.
+require File.expand_path("../message_bus.rb", __FILE__)
module VCAP::CloudController
class Runner
@@ -83,27 +84,31 @@ def setup_db
DB.connect(db_logger, @config[:db])
end
+ def development?
+ @development ||= false
+ end
+
def run!
db = setup_db
run_migrations = @run_migrations
- development = @development
- config = @config
-
- port = ENV["VCAP_APP_PORT"]
- port ||= @config[:port]
+ config = @config.dup
DB.apply_migrations(db) if run_migrations
- @thin_server = Thin::Server.new("0.0.0.0", port,
+ @thin_server = Thin::Server.new("0.0.0.0", config[:port],
:signals => false) do
use Rack::CommonLogger
+ VCAP::CloudController::MessageBus.register_components
+ VCAP::CloudController::MessageBus.register_routes
+
map "/" do
- DB.apply_migrations(db) if (run_migrations && development)
+ DB.apply_migrations(db) if (run_migrations && development?)
run VCAP::CloudController::Controller.new(config)
end
end
trap_signals
+
@thin_server.threaded = true
@thin_server.start!
end
@@ -127,6 +132,7 @@ def merge_vcap_config
pg_key = services.keys.select { |svc| svc =~ /postgres/i }.first
c = services[pg_key].first["credentials"]
@config[:db][:database] = "postgres://#{c["user"]}:#{c["password"]}@#{c["hostname"]}:#{c["port"]}/#{c["name"]}"
+ @config[:port] = ENV["VCAP_APP_PORT"]
end
end
end

0 comments on commit 4edadbb

Please sign in to comment.
Something went wrong with that request. Please try again.