Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Marketplace Gateway updates

 - Bundle updates: Add dependencies in vendor/cache
 - Marketplace gateway startup script accepts optional -c config file parameter
 - Remove a lot of unrequired dependencies (such as uuid and sqlite)
 - Change credentials and token for marketplace gateway
 - Collapsed appdirect configuration for appdirect endpoint
 - Read marketplace specific config from the same folder as markerplace_gateway.yml
 - Minor: Realign code, remove extra spaces

Change-Id: I43eed452a12feb903a8f29cd99a18c7cfb18b48d
  • Loading branch information...
commit 66eead35a5f4c494743b3bddc04ed307e89ef814 1 parent 0a9d9cb
Harshawardhan Gadgil authored
Showing with 370 additions and 390 deletions.
  1. +0 −4 marketplace/Gemfile
  2. +4 −14 marketplace/Gemfile.lock
  3. +17 −8 marketplace/bin/marketplace_gateway
  4. +2 −6 marketplace/config/appdirect.yml
  5. +3 −1 marketplace/config/marketplace_gateway.yml
  6. +1 −1  marketplace/lib/base/common.rb
  7. +12 −25 marketplace/lib/base/marketplace_async_gateway.rb
  8. +1 −3 marketplace/lib/base/marketplace_base.rb
  9. +161 −158 marketplace/lib/marketplaces/appdirect/appdirect_helper.rb
  10. +167 −167 marketplace/lib/marketplaces/appdirect/appdirect_marketplace.rb
  11. +1 −1  marketplace/spec/appdirect/appdirect_gateway_spec.rb
  12. +1 −2  marketplace/spec/appdirect/spec_helper.rb
  13. BIN  marketplace/vendor/cache/addressable-2.2.8.gem
  14. BIN  marketplace/vendor/cache/bcrypt-ruby-2.1.4.gem
  15. BIN  marketplace/vendor/cache/beefcake-0.3.7.gem
  16. BIN  marketplace/vendor/cache/builder-3.0.0.gem
  17. BIN  marketplace/vendor/cache/ci_reporter-1.7.1.gem
  18. BIN  marketplace/vendor/cache/curb-0.7.18.gem
  19. BIN  marketplace/vendor/cache/daemons-1.1.9.gem
  20. BIN  marketplace/vendor/cache/data_objects-0.10.8.gem
  21. BIN  marketplace/vendor/cache/datamapper-1.1.0.gem
  22. BIN  marketplace/vendor/cache/diff-lcs-1.1.3.gem
  23. BIN  marketplace/vendor/cache/dm-aggregates-1.1.0.gem
  24. BIN  marketplace/vendor/cache/dm-constraints-1.1.0.gem
  25. BIN  marketplace/vendor/cache/dm-core-1.1.0.gem
  26. BIN  marketplace/vendor/cache/dm-migrations-1.1.0.gem
  27. BIN  marketplace/vendor/cache/dm-serializer-1.1.0.gem
  28. BIN  marketplace/vendor/cache/dm-timestamps-1.1.0.gem
  29. BIN  marketplace/vendor/cache/dm-transactions-1.1.0.gem
  30. BIN  marketplace/vendor/cache/dm-types-1.1.0.gem
  31. BIN  marketplace/vendor/cache/dm-validations-1.1.0.gem
  32. BIN  marketplace/vendor/cache/do_sqlite3-0.10.8.gem
  33. BIN  marketplace/vendor/cache/em-http-request-1.0.0.beta.3.gem
  34. BIN  marketplace/vendor/cache/em-socksify-0.1.0.gem
  35. BIN  marketplace/vendor/cache/eventmachine_httpserver-0.2.1.gem
  36. BIN  marketplace/vendor/cache/fastercsv-1.5.5.gem
  37. BIN  marketplace/vendor/cache/http_parser.rb-0.5.3.gem
  38. BIN  marketplace/vendor/cache/httpclient-2.2.7.gem
  39. BIN  marketplace/vendor/cache/json-1.4.6.gem
  40. BIN  marketplace/vendor/cache/json_pure-1.7.5.gem
  41. BIN  marketplace/vendor/cache/macaddr-1.6.1.gem
  42. BIN  marketplace/vendor/cache/membrane-0.0.2.gem
  43. BIN  marketplace/vendor/cache/mime-types-1.19.gem
  44. BIN  marketplace/vendor/cache/multi_json-1.3.6.gem
  45. BIN  marketplace/vendor/cache/multipart-post-1.1.5.gem
  46. BIN  marketplace/vendor/cache/nats-0.4.24.gem
  47. BIN  marketplace/vendor/cache/oauth-0.4.6.gem
  48. BIN  marketplace/vendor/cache/posix-spawn-0.3.6.gem
  49. BIN  marketplace/vendor/cache/rack-1.4.1.gem
  50. BIN  marketplace/vendor/cache/rack-test-0.6.1.gem
  51. BIN  marketplace/vendor/cache/rake-0.9.2.2.gem
  52. BIN  marketplace/vendor/cache/redis-3.0.1.gem
  53. BIN  marketplace/vendor/cache/redis-namespace-1.2.1.gem
  54. BIN  marketplace/vendor/cache/redisk-0.2.2.gem
  55. BIN  marketplace/vendor/cache/resque-1.22.0.gem
  56. BIN  marketplace/vendor/cache/resque-status-0.3.3.gem
  57. BIN  marketplace/vendor/cache/rspec-2.11.0.gem
  58. BIN  marketplace/vendor/cache/rspec-core-2.11.1.gem
  59. BIN  marketplace/vendor/cache/rspec-expectations-2.11.2.gem
  60. BIN  marketplace/vendor/cache/rspec-mocks-2.11.2.gem
  61. BIN  marketplace/vendor/cache/ruby-hmac-0.4.0.gem
  62. BIN  marketplace/vendor/cache/rubyzip-0.9.9.gem
  63. BIN  marketplace/vendor/cache/simplecov-0.6.4.gem
  64. BIN  marketplace/vendor/cache/simplecov-html-0.5.3.gem
  65. BIN  marketplace/vendor/cache/simplecov-rcov-0.2.3.gem
  66. BIN  marketplace/vendor/cache/sinatra-1.2.8.gem
  67. BIN  marketplace/vendor/cache/stringex-1.2.2.gem
  68. BIN  marketplace/vendor/cache/systemu-2.5.2.gem
  69. BIN  marketplace/vendor/cache/thin-1.3.1.gem
  70. BIN  marketplace/vendor/cache/tilt-1.3.3.gem
  71. BIN  marketplace/vendor/cache/uuid-2.3.5.gem
  72. BIN  marketplace/vendor/cache/uuidtools-2.1.3.gem
  73. BIN  marketplace/vendor/cache/vegas-0.1.11.gem
  74. BIN  marketplace/vendor/cache/yajl-ruby-0.8.3.gem
View
4 marketplace/Gemfile
@@ -3,11 +3,7 @@ source :rubygems
gem 'eventmachine', :git => 'git://github.com/cloudfoundry/eventmachine.git', :branch => 'release-0.12.11-cf'
gem "em-http-request"
gem "ruby-hmac"
-gem "uuidtools"
-gem "datamapper", "~> 1.1.0"
gem "dm-core", "= 1.1.0"
-gem "do_sqlite3"
-gem "dm-sqlite-adapter"
gem "sinatra", "~> 1.2.3"
gem "oauth"
gem "json", "~> 1.4.6"
View
18 marketplace/Gemfile.lock
@@ -73,10 +73,10 @@ GEM
bcrypt-ruby (2.1.4)
beefcake (0.3.7)
builder (3.0.0)
- ci_reporter (1.7.0)
+ ci_reporter (1.7.1)
builder (>= 2.1.2)
curb (0.7.18)
- daemons (1.1.8)
+ daemons (1.1.9)
data_objects (0.10.8)
addressable (~> 2.1)
datamapper (1.1.0)
@@ -96,18 +96,12 @@ GEM
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)
@@ -135,7 +129,7 @@ GEM
http_parser.rb (0.5.3)
httpclient (2.2.7)
json (1.4.6)
- json_pure (1.7.4)
+ json_pure (1.7.5)
macaddr (1.6.1)
systemu (~> 2.5.0)
membrane (0.0.2)
@@ -175,7 +169,7 @@ GEM
rspec-core (2.11.1)
rspec-expectations (2.11.2)
diff-lcs (~> 1.1.3)
- rspec-mocks (2.11.1)
+ rspec-mocks (2.11.2)
ruby-hmac (0.4.0)
rubyzip (0.9.9)
simplecov (0.6.4)
@@ -206,10 +200,7 @@ PLATFORMS
DEPENDENCIES
ci_reporter
- datamapper (~> 1.1.0)
dm-core (= 1.1.0)
- dm-sqlite-adapter
- do_sqlite3
em-http-request
eventmachine!
json (~> 1.4.6)
@@ -222,7 +213,6 @@ DEPENDENCIES
simplecov
simplecov-rcov
sinatra (~> 1.2.3)
- uuidtools
vcap_common!
vcap_logging!
vcap_services_base!
View
25 marketplace/bin/marketplace_gateway
@@ -6,15 +6,13 @@ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
require 'bundler/setup'
require 'vcap_services_base'
+require 'optparse'
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'base/marketplace_async_gateway'
class VCAP::Services::Marketplace::Gateway < VCAP::Services::Base::Gateway
- def default_config_file
- File.join(File.dirname(__FILE__), '..', 'config', 'marketplace_gateway.yml')
- end
-
def additional_options
end
@@ -23,7 +21,18 @@ class VCAP::Services::Marketplace::Gateway < VCAP::Services::Base::Gateway
end
def load_config
- config_file = default_config_file
+ config_file = File.join(File.dirname(__FILE__), '..', 'config', 'marketplace_gateway.yml')
+
+ OptionParser.new do |opts|
+ opts.banner = "Usage: $0 [options]"
+ opts.on("-c", "--config [ARG]", "Configuration File") do |opt|
+ config_file = opt
+ end
+ opts.on("-h", "--help", "Help") do
+ puts opts
+ exit
+ end
+ end.parse!
begin
@config = parse_gateway_config(config_file)
@@ -33,7 +42,7 @@ class VCAP::Services::Marketplace::Gateway < VCAP::Services::Base::Gateway
end
marketplace = @config[:marketplace]
- marketplace_config = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'config', "#{marketplace}.yml"))
+ marketplace_config = YAML.load_file(File.join(File.dirname(config_file), "#{marketplace}.yml"))
marketplace_config = VCAP.symbolize_keys(marketplace_config)
@config = @config.merge(marketplace_config)
@@ -45,8 +54,8 @@ class VCAP::Services::Marketplace::Gateway < VCAP::Services::Base::Gateway
setup_pid
@config[:host] = VCAP.local_ip(@config[:ip_route])
- @config[:port] ||= VCAP.grab_ephemeral_port
- @config[:external_uri] = "#{@config[:host]}:#{@config[:port]}"
+ @config[:port] ||= VCAP.grab_ephemeral_port
+ @config[:url] = "http://#{@config[:host]}:#{@config[:port]}"
EM.run do
sg = async_gateway_class.new(@config)
View
8 marketplace/config/appdirect.yml
@@ -5,12 +5,8 @@ classname: "VCAP::Services::Marketplace::Appdirect::AppdirectMarketplace"
node_timeout: 15
# appdirect configuration
-# Not configured by default as it would require revealing
-# credentials to a non-local resource.
appdirect:
- scheme: https
- host: "dev3cloudfoundry.appdirect.com"
- port: "443"
- key: "k"
+ endpoint: "https://example.com"
+ key: "k"
secret: "s"
View
4 marketplace/config/marketplace_gateway.yml
@@ -2,7 +2,7 @@
cloud_controller_uri: api.vcap.me
ip_route: localhost
index: 0
-token: changebrokertoken
+token: changemarketplacetoken
mbus: nats://localhost:4222
logging:
level: debug
@@ -13,3 +13,5 @@ pid: /var/vcap/sys/run/marketplace.pid
# since this value is specific to interactions with #{marketplace}
marketplace: appdirect
+
+acls: [ "*@example.com" ]
View
2  marketplace/lib/base/common.rb
@@ -1,7 +1,7 @@
# Copyright (c) 2009-2011 VMware, Inc.
module VCAP
module Services
- module Marketplace
+ module Marketplace
module Common
def service_name
"MarketplaceGateway"
View
37 marketplace/lib/base/marketplace_async_gateway.rb
@@ -7,20 +7,18 @@ module Services
module Marketplace
class MarketplaceAsyncServiceGateway < VCAP::Services::AsynchronousServiceGateway
- REQ_OPTS = %w(mbus external_uri token cloud_controller_uri).map {|o| o.to_sym}
+ REQ_OPTS = %w(mbus url token cloud_controller_uri).map {|o| o.to_sym}
set :raise_errors, Proc.new {false}
set :show_exceptions, false
- attr_reader :ready_to_serve
-
def initialize(opts)
- super(opts)
+ super(opts)
end
def load_marketplace(opts)
marketplace_lib_path = File.join(File.dirname(__FILE__), '..', 'marketplaces', opts[:marketplace])
- @logger.info("Loading marketplace: #{opts[:marketplace]} from: #{marketplace_lib_path}")
+ @logger.info("Loading marketplace: #{opts[:marketplace]} from: #{marketplace_lib_path}")
$LOAD_PATH.unshift(marketplace_lib_path)
Dir[marketplace_lib_path + '/*.rb'].each do |file|
@@ -28,9 +26,11 @@ def load_marketplace(opts)
require f
end
- # HACK?? Is there a better way?
- eval "class VCAP::Services::Marketplace::MarketplaceClient < #{opts[:classname]} ; end"
- VCAP::Services::Marketplace::MarketplaceClient.new(opts)
+ # To minimize the amount of marketplace-specific code, the config file specifies the class that
+ # implements MarketplaceBase's abstract methods for this marketplace. So we need to translate the
+ # name of the class into the actual class object, and then create an instance of it.
+ klass = eval(opts[:classname])
+ klass.new(opts)
end
def setup(opts)
@@ -43,22 +43,13 @@ def setup(opts)
@logger = opts[:logger] || make_logger()
@token = opts[:token]
@hb_interval = opts[:heartbeat_interval] || 60
- @cld_ctrl_uri = http_uri(opts[:cloud_controller_uri] || default_cloud_controller_uri)
- @external_uri = opts[:external_uri]
+ @cld_ctrl_uri = http_uri(opts[:cloud_controller_uri] || "api.vcap.me")
@offering_uri = "#{@cld_ctrl_uri}/services/v1/offerings/"
- @router_start_channel = nil
@proxy_opts = opts[:proxy]
@handle_fetched = true # set to true in order to compatible with base asycn gateway.
@marketplace_client = load_marketplace(opts)
- @router_register_json = {
- :host => @host,
- :port => @port,
- :uris => [ @external_uri ],
- :tags => {:components => @marketplace_client.name},
- }.to_json
-
@catalog = {}
token_hdrs = VCAP::Services::Api::GATEWAY_TOKEN_HEADER
@@ -150,7 +141,6 @@ def on_exit(stop_event_loop=true)
# Binding a service
post "/gateway/v1/configurations/:service_id/handles" do
@logger.info("Got request_body=#{request_body}")
- #req = JSON.parse(request_body)
req = VCAP::Services::Api::GatewayBindRequest.decode(request_body)
@logger.info("Binding request for service=#{params['service_id']} options=#{req.inspect}")
@@ -203,7 +193,7 @@ def on_exit(stop_event_loop=true)
helpers do
def advertise_service_to_cc(offering)
- @logger.debug("advertise service offering to cloud_controller:#{offering.inspect}")
+ @logger.debug("advertise service offering #{offering.inspect} to cloud_controller: #{@offering_uri}")
return false unless offering
req = create_http_request(
@@ -213,9 +203,7 @@ def advertise_service_to_cc(offering)
f = Fiber.current
http = EM::HttpRequest.new(@offering_uri).post(req)
- http.callback do
- f.resume(http)
- end
+ http.callback { f.resume(http) }
http.errback { f.resume(http) }
Fiber.yield
@@ -259,10 +247,9 @@ def delete_offerings(label)
def fmt_error(e)
"#{e} [#{e.backtrace.join("|")}]"
end
-
end
+
end
end
end
end
-
View
4 marketplace/lib/base/marketplace_base.rb
@@ -4,8 +4,6 @@ module Services
module Marketplace
class Base
- VMWARE_ACLS = ["*@vmware.com", "*@rbcon.com"]
-
def initialize(opts_unused)
end
@@ -16,7 +14,7 @@ def name
def get_catalog
{}
end
-
+
def generate_cc_advertise_request(name, bsvc, active = true)
{}
end
View
319 marketplace/lib/marketplaces/appdirect/appdirect_helper.rb
@@ -7,200 +7,203 @@ module VCAP
module Services
module Marketplace
module Appdirect
- class AppdirectHelper
+ class AppdirectHelper
- include VCAP::Services::Marketplace::Appdirect
+ include VCAP::Services::Marketplace::Appdirect
- OFFERINGS_PATH = "custom/cloudfoundry/v1/offerings"
- SERVICES_PATH = "custom/cloudfoundry/v1/services"
+ OFFERINGS_PATH = "custom/cloudfoundry/v1/offerings"
+ SERVICES_PATH = "custom/cloudfoundry/v1/services"
- HEADER = {"Content-Type" => "application/json" , "Accept"=>"application/json"}
+ HEADER = {"Content-Type" => "application/json" , "Accept"=>"application/json"}
+ REQ_CONFIG = %w(endpoint key secret).map {|o| o.to_sym}
- def initialize(appdirect_config, logger)
- @logger = logger
+ def initialize(opts, logger)
+ @logger = logger
- raise("No appdirect config section provided in: #{appdirect_config.inspect}") unless appdirect_config[:appdirect]
+ raise("No appdirect config section provided in: #{opts.inspect}") unless opts[:appdirect]
- @scheme = appdirect_config[:appdirect][:scheme] || raise("No scheme provided")
- @host = appdirect_config[:appdirect][:host] || raise("No host provided")
- @appdirect_key = appdirect_config[:appdirect][:key] || raise("No Key Provided")
- @appdirect_secret = appdirect_config[:appdirect][:secret] || raise("No secret provided") unless @appdirect_secret
+ appdirect_config = opts[:appdirect]
- @consumer = OAuth::Consumer.new(@appdirect_key, @appdirect_secret)
- @access_token = OAuth::AccessToken.new(@consumer)
- end
+ missing_opts = REQ_CONFIG.select {|o| !appdirect_config.has_key? o}
+ raise ArgumentError, "Missing options: #{missing_opts.join(', ')}" unless missing_opts.empty?
- def get_catalog
- catalog = nil
- http = get_catalog_response
- if http.error.empty?
- if http.response_header.http_status == 200
- @logger.debug("Got catalog response #{http.response}")
- data = JSON.parse(http.response) #VCAP::Services::AppDirect::AppDirectCatalogResponse.decode(raw)
- catalog = {}
- data.each do |service|
- # Add checks for specific categories which determine whether the addon should be listed on cc
- @logger.debug("Got service '#{service["id"]}' from AppDirect")
- catalog[service["id"]] = service
- end
- @logger.info("Got #{catalog.keys.count} services from AppDirect")
- else
- @logger.warn("Failed to get catalog #{http.response}")
+ @appdirect_endpoint = appdirect_config[:endpoint]
+
+ @consumer = OAuth::Consumer.new(appdirect_config[:key], appdirect_config[:secret])
+ @access_token = OAuth::AccessToken.new(@consumer)
end
- else
- @logger.warn("Failed to get catalog: #{http.error}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_GET_LISTING, http.response_header.status)
- end
- return catalog
- end
- def purchase_service(order)
- new_serv = nil
- # TODO: Order needs to include UUID for User, Organization, AppSpace
- if order
- body = order.to_json
- http = post_order(body)
- if http.error.empty?
- if http.response_header.status >= 200 and http.response_header.status < 300
- new_serv = JSON.parse(http.response)
- return new_serv
+ def get_catalog
+ catalog = nil
+ http = get_catalog_response
+ if http.error.empty?
+ if http.response_header.http_status == 200
+ @logger.debug("Got catalog response #{http.response}")
+ data = JSON.parse(http.response) #VCAP::Services::AppDirect::AppDirectCatalogResponse.decode(raw)
+ catalog = {}
+ data.each do |service|
+ # Add checks for specific categories which determine whether the addon should be listed on cc
+ @logger.debug("Got service '#{service["id"]}' from AppDirect")
+ catalog[service["id"]] = service
+ end
+ @logger.info("Got #{catalog.keys.count} services from AppDirect")
+ else
+ @logger.warn("Failed to get catalog #{http.response}")
+ end
else
- # 400 bad request
- # 500 if AppDirect has issues
- # 503 if ISV is down
- @logger.warn("Bad status code posting #{body} was #{http.response}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_PURCHASE, http.response_header.status)
+ @logger.warn("Failed to get catalog: #{http.error}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_GET_LISTING, http.response_header.status)
end
- else
- @logger.warn("Error raised: #{http.error}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_PURCHASE, http.response_header.status)
+ return catalog
end
- else
- @logger.error("Order is required to purchase a service")
- end
- new_serv
- end
- def bind_service(order, order_id)
- update_serv = nil
- if order and order_id
- body = order.to_json
- http = post_bind_service(body, order_id)
-
- if http.error.empty?
- if http.response_header.status >= 200 and http.response_header.status < 300
- @logger.debug("Got http headers #{http.headers}")
- update_serv = JSON.parse(http.response)
- @logger.debug("Bound service #{order_id}")
+ def purchase_service(order)
+ new_serv = nil
+ # TODO: Order needs to include UUID for User, Organization, AppSpace
+ if order
+ body = order.to_json
+ http = post_order(body)
+ if http.error.empty?
+ if http.response_header.status >= 200 and http.response_header.status < 300
+ new_serv = JSON.parse(http.response)
+ return new_serv
+ else
+ # 400 bad request
+ # 500 if AppDirect has issues
+ # 503 if ISV is down
+ @logger.warn("Bad status code posting #{body} was #{http.response}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_PURCHASE, http.response_header.status)
+ end
+ else
+ @logger.warn("Error raised: #{http.error}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_PURCHASE, http.response_header.status)
+ end
else
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_BIND, http.response_header.status)
+ @logger.error("Order is required to purchase a service")
end
- else
- @logger.warn("Error raised: #{http.error}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_BIND, http.response_header.status)
+ new_serv
end
- else
- @logger.error("Order and Order Id are required to cancel a service")
- end
- update_serv
- end
- def unbind_service(order_id, binding_id)
- update_binding = false
- if binding_id and order_id
- http = delete_bind_service(order_id, binding_id)
+ def bind_service(order, order_id)
+ update_serv = nil
+ if order and order_id
+ body = order.to_json
+ http = post_bind_service(body, order_id)
+
+ if http.error.empty?
+ if http.response_header.status >= 200 and http.response_header.status < 300
+ @logger.debug("Got http headers #{http.headers}")
+ update_serv = JSON.parse(http.response)
+ @logger.debug("Bound service #{order_id}")
+ else
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_BIND, http.response_header.status)
+ end
+ else
+ @logger.warn("Error raised: #{http.error}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_BIND, http.response_header.status)
+ end
+ else
+ @logger.error("Order and Order Id are required to cancel a service")
+ end
+ update_serv
+ end
- if http.error.empty?
- if http.response_header.status >= 200 and http.response_header.status < 300
- update_binding = true
+ def unbind_service(order_id, binding_id)
+ update_binding = false
+ if binding_id and order_id
+ http = delete_bind_service(order_id, binding_id)
+
+ if http.error.empty?
+ if http.response_header.status >= 200 and http.response_header.status < 300
+ update_binding = true
+ else
+ @logger.warn("Invalid status code returned: #{http.response_header.status}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_UNBIND, http.response_header.status)
+ end
+ else
+ @logger.warn("Error raised: #{http.error}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_UNBIND, http.response_header.status)
+ end
else
- @logger.warn("Invalid status code returned: #{http.response_header.status}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_UNBIND, http.response_header.status)
+ @logger.error("Binding Id and Order Id are required to cancel a service")
end
- else
- @logger.warn("Error raised: #{http.error}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_UNBIND, http.response_header.status)
+ update_binding
end
- else
- @logger.error("Binding Id and Order Id are required to cancel a service")
- end
- update_binding
- end
- def cancel_service(order_id)
- cancel_serv = false
- if order_id
- http = delete_order(order_id)
- if http.response_header.status >= 200 and http.response_header.status < 300
- @logger.debug("Deleted #{order_id}")
- cancel_serv = true
- else
- @logger.warn("Invalid status code returned: #{http.response_header.status}")
- raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_CANCEL, http.response_header.status)
+ def cancel_service(order_id)
+ cancel_serv = false
+ if order_id
+ http = delete_order(order_id)
+ if http.response_header.status >= 200 and http.response_header.status < 300
+ @logger.debug("Deleted #{order_id}")
+ cancel_serv = true
+ else
+ @logger.warn("Invalid status code returned: #{http.response_header.status}")
+ raise AppdirectError.new(AppDirectError::APPDIRECT_ERROR_CANCEL, http.response_header.status)
+ end
+ else
+ @logger.error("Order Id is required to cancel a service")
+ end
+ cancel_serv
end
- else
- @logger.error("Order Id is required to cancel a service")
- end
- cancel_serv
- end
- private
- def get_catalog_response
- url = "#{@scheme}://#{@host}/api/#{OFFERINGS_PATH}"
- @logger.debug("About to get service listing from #{url}")
- f = Fiber.current
- http = EventMachine::HttpRequest.new(url).get(:head => HEADER)
- http.errback {f.resume(http)}
- http.callback {f.resume(http)}
+ private
+ def get_catalog_response
+ url = "#{@appdirect_endpoint}/api/#{OFFERINGS_PATH}"
+ @logger.debug("About to get service listing from #{url}")
+ f = Fiber.current
+ http = EventMachine::HttpRequest.new(url).get(:head => HEADER)
+ http.errback {f.resume(http)}
+ http.callback {f.resume(http)}
- return Fiber.yield
- end
+ return Fiber.yield
+ end
- def post_order(body)
- url = "#{@scheme}://#{@host}/api/#{SERVICES_PATH}"
- @logger.info("About to post #{url}")
- f = Fiber.current
- http = EventMachine::HttpRequest.new(url).post(:head => HEADER, :body => body)
- http.errback {f.resume(http)}
- http.callback {f.resume(http)}
+ def post_order(body)
+ url = "#{@appdirect_endpoint}/api/#{SERVICES_PATH}"
+ @logger.info("About to post #{url}")
+ f = Fiber.current
+ http = EventMachine::HttpRequest.new(url).post(:head => HEADER, :body => body)
+ http.errback {f.resume(http)}
+ http.callback {f.resume(http)}
- return Fiber.yield
- end
+ return Fiber.yield
+ end
- def delete_order(order_id)
- url = "#{@scheme}://#{@host}/api/#{SERVICES_PATH}/#{order_id}"
- @logger.info("About to delete #{url}")
- f = Fiber.current
- http = EventMachine::HttpRequest.new(url).delete(:head => HEADER)
- http.errback {f.resume(http)}
- http.callback {f.resume(http)}
+ def delete_order(order_id)
+ url = "#{@appdirect_endpoint}/api/#{SERVICES_PATH}/#{order_id}"
+ @logger.info("About to delete #{url}")
+ f = Fiber.current
+ http = EventMachine::HttpRequest.new(url).delete(:head => HEADER)
+ http.errback {f.resume(http)}
+ http.callback {f.resume(http)}
- return Fiber.yield
- end
+ return Fiber.yield
+ end
- def post_bind_service(body, order_id)
- url = "#{@scheme}://#{@host}/api/#{SERVICES_PATH}/#{order_id}/bindings"
- @logger.info("About to post #{url}")
- f = Fiber.current
- http = EventMachine::HttpRequest.new(url).post(:head => HEADER, :body => body)
- http.errback {f.resume(http)}
- http.callback {f.resume(http)}
+ def post_bind_service(body, order_id)
+ url = "#{@appdirect_endpoint}/api/#{SERVICES_PATH}/#{order_id}/bindings"
+ @logger.info("About to post #{url}")
+ f = Fiber.current
+ http = EventMachine::HttpRequest.new(url).post(:head => HEADER, :body => body)
+ http.errback {f.resume(http)}
+ http.callback {f.resume(http)}
- return Fiber.yield
- end
+ return Fiber.yield
+ end
- def delete_bind_service(order_id, binding_id)
- url = "#{@scheme}://#{@host}/api/#{SERVICES_PATH}/#{order_id}/bindings/#{binding_id}"
- @logger.info("About to delete binding #{url}")
- f = Fiber.current
- http = EventMachine::HttpRequest.new(url).delete(:head => HEADER)
- http.errback {f.resume(http)}
- http.callback {f.resume(http)}
+ def delete_bind_service(order_id, binding_id)
+ url = "#{@appdirect_endpoint}/api/#{SERVICES_PATH}/#{order_id}/bindings/#{binding_id}"
+ @logger.info("About to delete binding #{url}")
+ f = Fiber.current
+ http = EventMachine::HttpRequest.new(url).delete(:head => HEADER)
+ http.errback {f.resume(http)}
+ http.callback {f.resume(http)}
- return Fiber.yield
- end
+ return Fiber.yield
+ end
end
end
View
334 marketplace/lib/marketplaces/appdirect/appdirect_marketplace.rb
@@ -1,7 +1,6 @@
# Copyright (c) 2009-2012 VMware, Inc.
require 'fiber'
require 'dm-types'
-require 'nats/client'
require 'service_error'
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', '..')
@@ -13,172 +12,173 @@ module Marketplace
module Appdirect
class AppdirectMarketplace < VCAP::Services::Marketplace::Base
- include VCAP::Services::Base::Error
- include VCAP::Services::Marketplace::Appdirect
-
- def initialize(opts)
- super(opts)
-
- @logger = opts[:logger]
- @external_uri = opts[:external_uri]
- @node_timeout = opts[:node_timeout]
- @helper = AppdirectHelper.new(opts, @logger)
- end
-
- def name
- "AppDirect"
- end
-
- def get_catalog
- @helper.get_catalog
- end
-
- def generate_cc_advertise_request(name, bsvc, active = true)
- req = {}
- req[:label] = "#{name}-#{bsvc["version"]}"
- req[:active] = active && bsvc["active"]
- req[:description] = bsvc["description"]
-
- req[:supported_versions] = [ bsvc["version"] ]
- req[:version_aliases] = { "current" => bsvc["version"] }
-
- if bsvc["developers"] and bsvc["developers"].count > 0
- acls = []
- bsvc["developers"].each do |dev|
- acls << dev["email"]
- end
- req[:acls] = {}
- req[:acls][:wildcards] = VMWARE_ACLS
- req[:acls][:users] = acls
- end
-
- req[:url] = "http://#{@external_uri}"
-
- if bsvc["plans"] and bsvc["plans"].count > 0
- req[:plans] = []
- bsvc["plans"].each do |plan|
- req[:plans] << plan["id"]
- # No plan options yet
- end
- else
- req[:plans] = ["default"]
- end
-
- # No tags coming from AppDirect yet
- req[:tags] = ["default"]
- req[:timeout] = 5 + @node_timeout
- req
- end
-
- def provision_service(request_body)
- request = VCAP::Services::Api::GatewayProvisionRequest.decode(request_body)
- @logger.info("Provision request for label=#{request.label} plan=#{request.plan}, version=#{request.version}")
-
- id,version = request.label.split("-")
-
- order = {
- "user" => {
- "uuid" => nil,
- "email" => request.email
- },
- "offering" => {
- "id" => id,
- "version" => request.version || version
- },
- "configuration" => {
- "plan" => request.plan,
- "name" => request.name,
- "options" => {}
- }
- }
- receipt = @helper.purchase_service(order)
-
- if receipt
- @logger.debug("AppDirect service provisioned #{receipt.inspect}")
- credentials = receipt["credentials"] || {}
- credentials["name"] = receipt["id"] #id of service within the 3rd party ISV
- #We could store more info in credentials but these will never be used by apps or users
- svc = {
- :configuration => {:plan => request.plan, :name => request.name, :options => {} },
- :credentials => credentials,
- :service_id => receipt["uuid"],
- }
- success(svc)
- else
- @logger.warn("Invalid response to provision service label=#{request.label}")
- raise ServiceError.new(ServiceError::INTERNAL_ERROR, "Missing request -- cannot perform operation")
- end
- rescue => e
- if e.instance_of? ServiceError
- failure(e)
- else
- @logger.debug(e.inspect)
- @logger.warn("Can't provision service label=#{request.label}: #{fmt_error(e)}")
- internal_fail
- end
- end
-
- def unprovision_service(service_id)
- success = @helper.cancel_service(service_id)
- if success
- @logger.info("Successfully unprovisioned service #{service_id}")
- else
- @logger.info("Failed to unprovision service #{service_id}")
- end
- return success
- rescue => e
- if e.instance_of? ServiceError
- failure(e)
- else
- @logger.warn("Can't unprovision service service_id=#{service_id}: #{fmt_error(e)}")
- internal_fail
- end
- end
-
- def bind_service_instance(service_id, request)
- if service_id and request
- order = {
- "options" => request.binding_options
- }
- resp = @helper.bind_service(order, service_id)
- @logger.debug("Got response from AppDirect: #{resp.inspect}")
- binding = {
- :configuration => {:data => {:binding_options => request.binding_options}},
- :credentials => resp["credentials"],
- :service_id => resp["uuid"], #Important this is the binding_id
- }
- @logger.debug("Generated binding for CC: #{binding.inspect}")
- success(binding)
- else
- @logger.warn("Can't find service label=#{label}")
- raise ServiceError.new(ServiceError::INTERNAL_ERROR, "Missing request or service_id -- cannot perform operation")
- end
- rescue => e
- if e.instance_of? ServiceError
- failure(e)
- else
- @logger.warn("Can't bind service service_id=#{service_id}, request=#{request}: #{fmt_error(e)}")
- internal_fail
- end
- end
-
- def unbind_service(service_id, binding_id)
- success = @helper.unbind_service(service_id, binding_id)
- if success
- @logger.info("Successfully unbound service #{service_id} and binding id #{binding_id}")
- else
- @logger.info("Failed to unbind service #{service_id} and binding id #{binding_id}")
- end
- return success
- rescue => e
- if e.instance_of? ServiceError
- failure(e)
- else
- @logger.warn("Can't unprovision service service_id=#{service_id}: #{fmt_error(e)}")
- internal_fail
- end
- end
-
+ include VCAP::Services::Base::Error
+ include VCAP::Services::Marketplace::Appdirect
+
+ def initialize(opts)
+ super(opts)
+
+ @logger = opts[:logger]
+ @url = opts[:url]
+ @node_timeout = opts[:node_timeout]
+ @acls = opts[:acls]
+ @helper = AppdirectHelper.new(opts, @logger)
+ end
+
+ def name
+ "AppDirect"
+ end
+
+ def get_catalog
+ @helper.get_catalog
+ end
+
+ def generate_cc_advertise_request(name, bsvc, active = true)
+ req = {}
+ req[:label] = "#{name}-#{bsvc["version"]}"
+ req[:active] = active && bsvc["active"]
+ req[:description] = bsvc["description"]
+
+ req[:supported_versions] = [ bsvc["version"] ]
+ req[:version_aliases] = { "current" => bsvc["version"] }
+
+ if bsvc["developers"] and bsvc["developers"].count > 0
+ acls = []
+ bsvc["developers"].each do |dev|
+ acls << dev["email"]
+ end
+ req[:acls] = {}
+ req[:acls][:wildcards] = @acls
+ req[:acls][:users] = acls
+ end
+
+ req[:url] = @url
+
+ if bsvc["plans"] and bsvc["plans"].count > 0
+ req[:plans] = []
+ bsvc["plans"].each do |plan|
+ req[:plans] << plan["id"]
+ # No plan options yet
+ end
+ else
+ req[:plans] = ["default"]
+ end
+
+ req[:tags] = ["default"] # No tags coming from AppDirect yet
+ req[:timeout] = 5 + @node_timeout
+ req
+ end
+
+ def provision_service(request_body)
+ request = VCAP::Services::Api::GatewayProvisionRequest.decode(request_body)
+ @logger.info("Provision request for label=#{request.label} plan=#{request.plan}, version=#{request.version}")
+
+ id,version = request.label.split("-")
+
+ order = {
+ "user" => {
+ "uuid" => nil,
+ "email" => request.email
+ },
+ "offering" => {
+ "id" => id,
+ "version" => request.version || version
+ },
+ "configuration" => {
+ "plan" => request.plan,
+ "name" => request.name,
+ "options" => {}
+ }
+ }
+ receipt = @helper.purchase_service(order)
+
+ if receipt
+ @logger.debug("AppDirect service provisioned #{receipt.inspect}")
+ credentials = receipt["credentials"] || {}
+ credentials["name"] = receipt["id"] #id of service within the 3rd party ISV
+ #We could store more info in credentials but these will never be used by apps or users
+ svc = {
+ :configuration => {:plan => request.plan, :name => request.name, :options => {} },
+ :credentials => credentials,
+ :service_id => receipt["uuid"],
+ }
+ success(svc)
+ else
+ @logger.warn("Invalid response to provision service label=#{request.label}")
+ raise ServiceError.new(ServiceError::INTERNAL_ERROR, "Missing request -- cannot perform operation")
+ end
+ rescue => e
+ if e.instance_of? ServiceError
+ failure(e)
+ else
+ @logger.debug(e.inspect)
+ @logger.warn("Can't provision service label=#{request.label}: #{fmt_error(e)}")
+ internal_fail
+ end
+ end
+
+ def unprovision_service(service_id)
+ success = @helper.cancel_service(service_id)
+ if success
+ @logger.info("Successfully unprovisioned service #{service_id}")
+ else
+ @logger.info("Failed to unprovision service #{service_id}")
+ end
+ return success
+ rescue => e
+ if e.instance_of? ServiceError
+ failure(e)
+ else
+ @logger.warn("Can't unprovision service service_id=#{service_id}: #{fmt_error(e)}")
+ internal_fail
+ end
+ end
+
+ def bind_service_instance(service_id, request)
+ if service_id and request
+ order = {
+ "options" => request.binding_options
+ }
+ resp = @helper.bind_service(order, service_id)
+ @logger.debug("Got response from AppDirect: #{resp.inspect}")
+ binding = {
+ :configuration => {:data => {:binding_options => request.binding_options}},
+ :credentials => resp["credentials"],
+ :service_id => resp["uuid"], #Important this is the binding_id
+ }
+ @logger.debug("Generated binding for CC: #{binding.inspect}")
+ success(binding)
+ else
+ @logger.warn("Can't find service label=#{label}")
+ raise ServiceError.new(ServiceError::INTERNAL_ERROR, "Missing request or service_id -- cannot perform operation")
+ end
+ rescue => e
+ if e.instance_of? ServiceError
+ failure(e)
+ else
+ @logger.warn("Can't bind service service_id=#{service_id}, request=#{request}: #{fmt_error(e)}")
+ internal_fail
+ end
+ end
+
+ def unbind_service(service_id, binding_id)
+ success = @helper.unbind_service(service_id, binding_id)
+ begin
+ if success
+ @logger.info("Successfully unbound service #{service_id} and binding id #{binding_id}")
+ else
+ @logger.info("Failed to unbind service #{service_id} and binding id #{binding_id}")
+ end
+ return success
+ rescue => e
+ if e.instance_of? ServiceError
+ failure(e)
+ else
+ @logger.warn("Can't unprovision service service_id=#{service_id}: #{fmt_error(e)}")
+ internal_fail
+ end
+ end
+ end
end
end
end
View
2  marketplace/spec/appdirect/appdirect_gateway_spec.rb
@@ -30,7 +30,7 @@ class MarketplaceAsyncServiceGateway
puts "Initializing..."
sleep 1
end
-
+
@app_session = Rack::Test::Session.new(Rack::MockSession.new(@gateway))
@rack_env = {
View
3  marketplace/spec/appdirect/spec_helper.rb
@@ -77,11 +77,10 @@ def load_config()
appdirect_config = symbolize_keys(appdirect_config)
config = config.merge(appdirect_config)
- config[:external_uri] =
config[:logger] = make_logger()
config[:host] = VCAP.local_ip(config[:ip_route])
config[:port] ||= VCAP.grab_ephemeral_port
- config[:external_uri] = "#{config[:host]}:#{config[:port]}"
+ config[:url] = "http://#{config[:host]}:#{config[:port]}"
config
end
View
BIN  marketplace/vendor/cache/addressable-2.2.8.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/bcrypt-ruby-2.1.4.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/beefcake-0.3.7.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/builder-3.0.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/ci_reporter-1.7.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/curb-0.7.18.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/daemons-1.1.9.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/data_objects-0.10.8.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/datamapper-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/diff-lcs-1.1.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-aggregates-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-constraints-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-core-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-migrations-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-serializer-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-timestamps-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-transactions-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-types-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/dm-validations-1.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/do_sqlite3-0.10.8.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/em-http-request-1.0.0.beta.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/em-socksify-0.1.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/eventmachine_httpserver-0.2.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/fastercsv-1.5.5.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/http_parser.rb-0.5.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/httpclient-2.2.7.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/json-1.4.6.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/json_pure-1.7.5.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/macaddr-1.6.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/membrane-0.0.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/mime-types-1.19.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/multi_json-1.3.6.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/multipart-post-1.1.5.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/nats-0.4.24.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/oauth-0.4.6.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/posix-spawn-0.3.6.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rack-1.4.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rack-test-0.6.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rake-0.9.2.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/redis-3.0.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/redis-namespace-1.2.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/redisk-0.2.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/resque-1.22.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/resque-status-0.3.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rspec-2.11.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rspec-core-2.11.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rspec-expectations-2.11.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rspec-mocks-2.11.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/ruby-hmac-0.4.0.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/rubyzip-0.9.9.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/simplecov-0.6.4.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/simplecov-html-0.5.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/simplecov-rcov-0.2.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/sinatra-1.2.8.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/stringex-1.2.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/systemu-2.5.2.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/thin-1.3.1.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/tilt-1.3.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/uuid-2.3.5.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/uuidtools-2.1.3.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/vegas-0.1.11.gem
Binary file not shown
View
BIN  marketplace/vendor/cache/yajl-ruby-0.8.3.gem
Binary file not shown

0 comments on commit 66eead3

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