Permalink
Browse files

prototype service broker implemenation

  - add API to create and delete a brokered service
  - add service_broker domain name registration
  - support load pre-defined brokered services from configuration file

Change-Id: Ieac9f1b2dde76acd48205e58691ee2e5669272db
  • Loading branch information...
1 parent 6d9e26a commit d5053d37bb64bcf754d9502689f5692ec79fcacf @andl andl committed Aug 31, 2011
Showing with 969 additions and 30 deletions.
  1. +11 −3 base/lib/base/asynchronous_service_gateway.rb
  2. +2 −0 base/lib/base/base.rb
  3. +42 −27 base/lib/base/gateway.rb
  4. +1 −0 service_broker/.gitignore
  5. +25 −0 service_broker/Gemfile
  6. +127 −0 service_broker/Gemfile.lock
  7. +1 −0 service_broker/README
  8. +39 −0 service_broker/Rakefile
  9. +94 −0 service_broker/bin/service_broker
  10. +26 −0 service_broker/config/pre_defined_services.yml
  11. +15 −0 service_broker/config/service_broker.yml
  12. +464 −0 service_broker/lib/service_broker/async_gateway.rb
  13. +41 −0 service_broker/spec/Rakefile
  14. +51 −0 service_broker/spec/service_broker_spec.rb
  15. +30 −0 service_broker/spec/spec_helper.rb
  16. BIN service_broker/vendor/cache/addressable-2.2.4.gem
  17. BIN service_broker/vendor/cache/bcrypt-ruby-2.1.4.gem
  18. BIN service_broker/vendor/cache/builder-3.0.0.gem
  19. BIN service_broker/vendor/cache/ci_reporter-1.6.4.gem
  20. BIN service_broker/vendor/cache/daemons-1.1.2.gem
  21. BIN service_broker/vendor/cache/data_objects-0.10.3.gem
  22. BIN service_broker/vendor/cache/datamapper-1.1.0.gem
  23. BIN service_broker/vendor/cache/diff-lcs-1.1.2.gem
  24. BIN service_broker/vendor/cache/dm-aggregates-1.1.0.gem
  25. BIN service_broker/vendor/cache/dm-constraints-1.1.0.gem
  26. BIN service_broker/vendor/cache/dm-core-1.1.0.gem
  27. BIN service_broker/vendor/cache/dm-do-adapter-1.1.0.gem
  28. BIN service_broker/vendor/cache/dm-migrations-1.1.0.gem
  29. BIN service_broker/vendor/cache/dm-serializer-1.1.0.gem
  30. BIN service_broker/vendor/cache/dm-sqlite-adapter-1.1.0.gem
  31. BIN service_broker/vendor/cache/dm-timestamps-1.1.0.gem
  32. BIN service_broker/vendor/cache/dm-transactions-1.1.0.gem
  33. BIN service_broker/vendor/cache/dm-types-1.1.0.gem
  34. BIN service_broker/vendor/cache/dm-validations-1.1.0.gem
  35. BIN service_broker/vendor/cache/do_sqlite3-0.10.3.gem
  36. BIN service_broker/vendor/cache/em-http-request-0.3.0.gem
  37. BIN service_broker/vendor/cache/escape_utils-0.2.3.gem
  38. BIN service_broker/vendor/cache/eventmachine-0.12.10.gem
  39. BIN service_broker/vendor/cache/fastercsv-1.5.4.gem
  40. BIN service_broker/vendor/cache/json-1.4.6.gem
  41. BIN service_broker/vendor/cache/json_pure-1.5.1.gem
  42. BIN service_broker/vendor/cache/little-plugger-1.1.2.gem
  43. BIN service_broker/vendor/cache/logging-1.5.0.gem
  44. BIN service_broker/vendor/cache/nats-0.4.8.gem
  45. BIN service_broker/vendor/cache/posix-spawn-0.3.6.gem
  46. BIN service_broker/vendor/cache/rack-1.2.2.gem
  47. BIN service_broker/vendor/cache/rack-test-0.5.7.gem
  48. BIN service_broker/vendor/cache/rake-0.8.7.gem
  49. BIN service_broker/vendor/cache/rcov-0.9.9.gem
  50. BIN service_broker/vendor/cache/rspec-2.5.0.gem
  51. BIN service_broker/vendor/cache/rspec-core-2.5.1.gem
  52. BIN service_broker/vendor/cache/rspec-expectations-2.5.0.gem
  53. BIN service_broker/vendor/cache/rspec-mocks-2.5.0.gem
  54. BIN service_broker/vendor/cache/sinatra-1.2.1.gem
  55. BIN service_broker/vendor/cache/stringex-1.2.1.gem
  56. BIN service_broker/vendor/cache/thin-1.2.11.gem
  57. BIN service_broker/vendor/cache/tilt-1.2.2.gem
  58. BIN service_broker/vendor/cache/uuidtools-2.1.2.gem
  59. BIN service_broker/vendor/cache/vcap_common-0.99.gem
  60. BIN service_broker/vendor/cache/vcap_logging-0.1.0.gem
  61. BIN service_broker/vendor/cache/yajl-ruby-0.8.2.gem
@@ -12,6 +12,7 @@
$:.unshift(File.expand_path("../../../../../lib", __FILE__))
require 'json_message'
require 'services/api'
+require 'services/api/const'
require 'service_error'
@@ -36,6 +37,11 @@ class VCAP::Services::AsynchronousServiceGateway < Sinatra::Base
def initialize(opts)
super
+ setup(opts)
+ end
+
+ # setup the environment
+ def setup(opts)
missing_opts = REQ_OPTS.select {|o| !opts.has_key? o}
raise ArgumentError, "Missing options: #{missing_opts.join(', ')}" unless missing_opts.empty?
@service = opts[:service]
@@ -66,9 +72,11 @@ def initialize(opts)
:url => @service[:url],
:active => false
}.to_json
+
+ token_hdrs = VCAP::Services::Api::GATEWAY_TOKEN_HEADER
@cc_req_hdrs = {
- 'Content-Type' => 'application/json',
- 'X-VCAP-Service-Token' => @token,
+ 'Content-Type' => 'application/json',
+ token_hdrs => @token,
}
@proxy_opts = opts[:proxy]
@@ -329,7 +337,7 @@ def update_service_handle(handle, &cb)
def async_mode(timeout=@node_timeout)
request.env['__async_timer'] = EM.add_timer(timeout) do
- @logger.warn("Service Unavailable")
+ @logger.warn("Request timeout in #{timeout} seconds.")
error_msg = ServiceError.new(ServiceError::SERVICE_UNAVAILABLE).to_hash
err_body = error_msg['msg'].to_json()
request.env['async.callback'].call(
@@ -79,6 +79,8 @@ def shutdown()
# Subclasses VCAP::Services::Base::{Node,Provisioner} implement the
# following methods. (Note that actual service Provisioner or Node
# implementations should NOT need to touch these!)
+
+ # TODO on_connect_node should be on_connect_nats
abstract :on_connect_node
abstract :flavor # "Provisioner" or "Node"
abstract :varz_details
@@ -32,8 +32,7 @@ class VCAP::Services::Base::Gateway
CC_CONFIG_FILE = File.expand_path("../../../../../cloud_controller/config/cloud_controller.yml", __FILE__)
- def start
-
+ def parse_config
config_file = default_config_file
OptionParser.new do |opts|
@@ -48,55 +47,71 @@ def start
end.parse!
begin
- config = parse_gateway_config(config_file)
+ @config = parse_gateway_config(config_file)
rescue => e
puts "Couldn't read config file: #{e}"
exit
end
+ end
- VCAP::Logging.setup_from_config(config[:logging])
+ def setup_vcap_logging
+ VCAP::Logging.setup_from_config(@config[:logging])
# Use the current running binary name for logger identity name, since service gateway only has one instance now.
logger = VCAP::Logging.logger(File.basename($0))
- config[:logger] = logger
+ @config[:logger] = logger
+ end
- if config[:pid]
- pf = VCAP::PidFile.new(config[:pid])
+ def setup_pid
+ if @config[:pid]
+ pf = VCAP::PidFile.new(@config[:pid])
pf.unlink_at_exit
end
+ end
- config[:host] = VCAP.local_ip(config[:ip_route])
- config[:port] ||= VCAP.grab_ephemeral_port
- config[:service][:label] = "#{config[:service][:name]}-#{config[:service][:version]}"
- config[:service][:url] = "http://#{config[:host]}:#{config[:port]}"
- cloud_controller_uri = config[:cloud_controller_uri] || default_cloud_controller_uri
- node_timeout = config[:node_timeout] || 5
+ def start
+ parse_config
+
+ setup_vcap_logging
+
+ setup_pid
+
+ @config[:host] = VCAP.local_ip(@config[:ip_route])
+ @config[:port] ||= VCAP.grab_ephemeral_port
+ @config[:service][:label] = "#{@config[:service][:name]}-#{@config[:service][:version]}"
+ @config[:service][:url] = "http://#{@config[:host]}:#{@config[:port]}"
+ node_timeout = @config[:node_timeout] || 5
+ cloud_controller_uri = @config[:cloud_controller_uri] || default_cloud_controller_uri
# Go!
EM.run do
sp = provisioner_class.new(
- :logger => logger,
- :index => config[:index],
- :version => config[:service][:version],
- :ip_route => config[:ip_route],
- :mbus => config[:mbus],
+ :logger => @config[:logger],
+ :index => @config[:index],
+ :version => @config[:service][:version],
+ :ip_route => @config[:ip_route],
+ :mbus => @config[:mbus],
:node_timeout => node_timeout,
- :z_interval => config[:z_interval],
- :allow_over_provisioning => config[:allow_over_provisioning]
+ :z_interval => @config[:z_interval],
+ :allow_over_provisioning => @config[:allow_over_provisioning]
)
- sg = VCAP::Services::AsynchronousServiceGateway.new(
- :proxy => config[:proxy],
- :service => config[:service],
- :token => config[:token],
- :logger => logger,
+ sg = async_gateway_class.new(
+ :proxy => @config[:proxy],
+ :service => @config[:service],
+ :token => @config[:token],
+ :logger => @config[:logger],
:provisioner => sp,
:node_timeout => node_timeout,
:cloud_controller_uri => cloud_controller_uri,
- :check_orphan_interval => config[:check_orphan_interval] || -1
+ :check_orphan_interval => @config[:check_orphan_interval] || -1
)
- Thin::Server.start(config[:host], config[:port], sg)
+ Thin::Server.start(@config[:host], @config[:port], sg)
end
end
+ def async_gateway_class
+ VCAP::Services::AsynchronousServiceGateway
+ end
+
def default_cloud_controller_uri
config = YAML.load_file(CC_CONFIG_FILE)
config['external_uri'] || "api.vcap.me"
@@ -0,0 +1 @@
+*.db
@@ -0,0 +1,25 @@
+source "http://rubygems.org"
+
+gem "nats", '>= 0.4.8'
+gem "datamapper", ">= 0.10.2"
+gem "do_sqlite3", :require => nil
+gem "dm-sqlite-adapter"
+gem "dm-types"
+gem "eventmachine"
+gem "em-http-request"
+gem "json"
+gem "uuidtools"
+gem "thin"
+gem "sinatra"
+
+gem 'vcap_common', :require => ['vcap/common', 'vcap/component']
+gem 'vcap_logging', :require => ['vcap/logging']
+
+group :test do
+ gem "rake"
+ gem "rspec"
+ gem "rack-test"
+ gem "rcov"
+ gem "ci_reporter"
+end
+
@@ -0,0 +1,127 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ addressable (2.2.4)
+ bcrypt-ruby (2.1.4)
+ builder (3.0.0)
+ ci_reporter (1.6.4)
+ builder (>= 2.1.2)
+ daemons (1.1.2)
+ data_objects (0.10.3)
+ addressable (~> 2.1)
+ datamapper (1.1.0)
+ dm-aggregates (= 1.1.0)
+ dm-constraints (= 1.1.0)
+ dm-core (= 1.1.0)
+ dm-migrations (= 1.1.0)
+ dm-serializer (= 1.1.0)
+ dm-timestamps (= 1.1.0)
+ dm-transactions (= 1.1.0)
+ dm-types (= 1.1.0)
+ dm-validations (= 1.1.0)
+ diff-lcs (1.1.2)
+ dm-aggregates (1.1.0)
+ dm-core (~> 1.1.0)
+ dm-constraints (1.1.0)
+ dm-core (~> 1.1.0)
+ dm-core (1.1.0)
+ addressable (~> 2.2.4)
+ dm-do-adapter (1.1.0)
+ data_objects (~> 0.10.2)
+ dm-core (~> 1.1.0)
+ dm-migrations (1.1.0)
+ dm-core (~> 1.1.0)
+ dm-serializer (1.1.0)
+ dm-core (~> 1.1.0)
+ fastercsv (~> 1.5.4)
+ json (~> 1.4.6)
+ dm-sqlite-adapter (1.1.0)
+ dm-do-adapter (~> 1.1.0)
+ do_sqlite3 (~> 0.10.2)
+ dm-timestamps (1.1.0)
+ dm-core (~> 1.1.0)
+ dm-transactions (1.1.0)
+ dm-core (~> 1.1.0)
+ dm-types (1.1.0)
+ bcrypt-ruby (~> 2.1.4)
+ dm-core (~> 1.1.0)
+ fastercsv (~> 1.5.4)
+ json (~> 1.4.6)
+ stringex (~> 1.2.0)
+ uuidtools (~> 2.1.2)
+ dm-validations (1.1.0)
+ dm-core (~> 1.1.0)
+ do_sqlite3 (0.10.3)
+ data_objects (= 0.10.3)
+ em-http-request (0.3.0)
+ addressable (>= 2.0.0)
+ escape_utils
+ eventmachine (>= 0.12.9)
+ escape_utils (0.2.3)
+ eventmachine (0.12.10)
+ fastercsv (1.5.4)
+ json (1.4.6)
+ json_pure (1.5.1)
+ little-plugger (1.1.2)
+ logging (1.5.0)
+ little-plugger (>= 1.1.2)
+ nats (0.4.8)
+ daemons (>= 1.1.0)
+ eventmachine (>= 0.12.10)
+ json_pure (>= 1.5.1)
+ posix-spawn (0.3.6)
+ rack (1.2.2)
+ rack-test (0.5.7)
+ rack (>= 1.0)
+ rake (0.8.7)
+ rcov (0.9.9)
+ rspec (2.5.0)
+ rspec-core (~> 2.5.0)
+ rspec-expectations (~> 2.5.0)
+ rspec-mocks (~> 2.5.0)
+ rspec-core (2.5.1)
+ rspec-expectations (2.5.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.5.0)
+ sinatra (1.2.1)
+ rack (~> 1.1)
+ tilt (< 2.0, >= 1.2.2)
+ stringex (1.2.1)
+ thin (1.2.11)
+ daemons (>= 1.0.9)
+ eventmachine (>= 0.12.6)
+ rack (>= 1.0.0)
+ tilt (1.2.2)
+ uuidtools (2.1.2)
+ vcap_common (0.99)
+ eventmachine (~> 0.12.10)
+ logging (>= 1.5.0)
+ nats
+ posix-spawn
+ thin
+ yajl-ruby
+ vcap_logging (0.1.0)
+ yajl-ruby (0.8.2)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ ci_reporter
+ datamapper (>= 0.10.2)
+ dm-sqlite-adapter
+ dm-types
+ do_sqlite3
+ em-http-request
+ eventmachine
+ json
+ nats (>= 0.4.8)
+ rack-test
+ rake
+ rcov
+ rspec
+ sinatra
+ thin
+ uuidtools
+ vcap_common
+ vcap_logging
@@ -0,0 +1 @@
+Cloud Foundry Service Broker enables consumption of legacy, non-CF services by CF apps using standard Cloud Foundry APIs and bindings.
@@ -0,0 +1,39 @@
+require 'rake'
+
+desc "Run specs"
+task "spec" => ["bundler:install:test", "test:spec"]
+
+desc "Run specs using RCov"
+task "spec:rcov" => ["bundler:install:test", "test:spec:rcov"]
+
+namespace "bundler" do
+ desc "Install gems"
+ task "install" do
+ sh("bundle install")
+ end
+
+ desc "Install gems for test"
+ task "install:test" do
+ sh("bundle install --without development production")
+ end
+
+ desc "Install gems for production"
+ task "install:production" do
+ sh("bundle install --without development test")
+ end
+
+ desc "Install gems for development"
+ task "install:development" do
+ sh("bundle install --without test production")
+ end
+end
+
+namespace "test" do
+ task "spec" do |t|
+ sh("cd spec && ../../base/bin/nats-util start && rake spec && ../../base/bin/nats-util stop")
+ end
+
+ task "spec:rcov" do |t|
+ sh("cd spec && rake spec:rcov")
+ end
+end
Oops, something went wrong.

0 comments on commit d5053d3

Please sign in to comment.