diff --git a/lib/stacker_bee/client.rb b/lib/stacker_bee/client.rb
index 27bad20..1c9ffc4 100644
--- a/lib/stacker_bee/client.rb
+++ b/lib/stacker_bee/client.rb
@@ -38,7 +38,9 @@ def middlewares
builder.use Middleware::EndpointNormalizer, api: self.class.api
builder.use Middleware::RemoveEmptyStrings
- builder.use Middleware::CloudStackAPI, api_key: configuration.api_key
+ builder.use Middleware::CloudStackAPI,
+ api_key: configuration.api_key,
+ url: configuration.url
configuration.middlewares.call builder
diff --git a/lib/stacker_bee/middleware/cloud_stack_api.rb b/lib/stacker_bee/middleware/cloud_stack_api.rb
index 75c15f2..295fce7 100644
--- a/lib/stacker_bee/middleware/cloud_stack_api.rb
+++ b/lib/stacker_bee/middleware/cloud_stack_api.rb
@@ -2,7 +2,6 @@ module StackerBee
module Middleware
class CloudStackAPI < Base
RESPONSE_TYPE = 'json'
- DEFAULT_PATH = '/client/api/'
def before(env)
env.request.params.merge!(
@@ -10,7 +9,7 @@ def before(env)
command: env.request.endpoint_name,
response: RESPONSE_TYPE
)
- env.request.path ||= DEFAULT_PATH
+ env.request.path ||= URI.parse(url).path
end
end
end
diff --git a/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/raises_a_helpful_exception.yml b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/raises_a_helpful_exception.yml
new file mode 100644
index 0000000..33eda1a
--- /dev/null
+++ b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/raises_a_helpful_exception.yml
@@ -0,0 +1,33 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: ?apiKey=&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v0.8.9
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - '*/*'
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Content-Type:
+ - text/javascript; charset=UTF-8
+ Content-Length:
+ - '1727'
+ Server:
+ - Jetty(6.1.26)
+ body:
+ encoding: UTF-8
+ string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"b32dc958-b904-11e3-b3f0-080027079e3d","name":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":0,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"b32e02b0-b904-11e3-b3f0-080027079e3d","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2014-03-31T18:45:58+0000","state":"enabled","account":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","apikey":"","secretkey":"","accountid":"b32dc958-b904-11e3-b3f0-080027079e3d","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
+ ] } }'
+ http_version:
+ recorded_at: Fri, 21 Nov 2014 19:49:56 GMT
+recorded_with: VCR 2.9.3
diff --git a/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/refuses_to_connect.yml b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/refuses_to_connect.yml
new file mode 100644
index 0000000..9d0a1bd
--- /dev/null
+++ b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/given_an_nonexistant_path/refuses_to_connect.yml
@@ -0,0 +1,77 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: ?apiKey=&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v0.8.9
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - '*/*'
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Content-Type:
+ - text/javascript; charset=UTF-8
+ Content-Length:
+ - '1727'
+ Server:
+ - Jetty(6.1.26)
+ body:
+ encoding: UTF-8
+ string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"b32dc958-b904-11e3-b3f0-080027079e3d","name":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":0,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"b32e02b0-b904-11e3-b3f0-080027079e3d","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2014-03-31T18:45:58+0000","state":"enabled","account":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","apikey":"","secretkey":"","accountid":"b32dc958-b904-11e3-b3f0-080027079e3d","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
+ ] } }'
+ http_version:
+ recorded_at: Fri, 21 Nov 2014 20:16:07 GMT
+- request:
+ method: get
+ uri: /not/a/real/endpoint?apiKey=&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v0.8.9
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - '*/*'
+ response:
+ status:
+ code: 404
+ message: Not Found
+ headers:
+ Cache-Control:
+ - must-revalidate,no-cache,no-store
+ Content-Type:
+ - text/html; charset=iso-8859-1
+ Content-Length:
+ - '1287'
+ Server:
+ - Jetty(6.1.26)
+ body:
+ encoding: UTF-8
+ string: "\n\n\nError 404 NOT_FOUND\n\n\nHTTP
+ ERROR: 404
\nProblem accessing /not/a/real/endpoint. Reason:\n
+ \ NOT_FOUND
\n
Powered by Jetty://\n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n\n\n"
+ http_version:
+ recorded_at: Fri, 21 Nov 2014 20:20:21 GMT
+recorded_with: VCR 2.9.3
diff --git a/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/with_a_nonexistant_path/raises_a_client_error.yml b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/with_a_nonexistant_path/raises_a_client_error.yml
new file mode 100644
index 0000000..1493480
--- /dev/null
+++ b/spec/cassettes/A_response_to_a_request_sent_to_the_CloudStack_API/with_a_nonexistant_path/raises_a_client_error.yml
@@ -0,0 +1,47 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: /not/a/real/endpoint?apiKey=&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v0.8.9
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - '*/*'
+ response:
+ status:
+ code: 404
+ message: Not Found
+ headers:
+ Cache-Control:
+ - must-revalidate,no-cache,no-store
+ Content-Type:
+ - text/html; charset=iso-8859-1
+ Content-Length:
+ - '1287'
+ Server:
+ - Jetty(6.1.26)
+ body:
+ encoding: UTF-8
+ string: "\n\n\nError 404 NOT_FOUND\n\n\nHTTP
+ ERROR: 404
\nProblem accessing /not/a/real/endpoint. Reason:\n
+ \ NOT_FOUND
\n
Powered by Jetty://\n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n
+ \ \n \n\n\n"
+ http_version:
+ recorded_at: Mon, 24 Nov 2014 16:10:28 GMT
+recorded_with: VCR 2.9.3
diff --git a/spec/integration/request_spec.rb b/spec/integration/request_spec.rb
index 0a4a7dc..9b024dc 100644
--- a/spec/integration/request_spec.rb
+++ b/spec/integration/request_spec.rb
@@ -3,7 +3,9 @@
describe 'A response to a request sent to the CloudStack API', :vcr do
subject { client.list_accounts }
- let(:url) { CONFIG['url'] }
+ let(:config_url) { CONFIG['url'] }
+ let(:uri) { URI.parse(config_url) }
+ let(:url) { uri.to_s }
let(:config_hash) do
{
url: url,
@@ -35,6 +37,13 @@
end
end
+ context 'with a nonexistant path', :regression do
+ before { uri.path = '/not/a/real/endpoint' }
+ it 'raises a client error' do
+ expect { subject }.to raise_error(StackerBee::ClientError)
+ end
+ end
+
context 'trailing slash in URL', :regression do
let(:url) { CONFIG['url'].gsub(/\/$/, '') + '/' }
it 'makes request with trailing slash' do
diff --git a/spec/units/stacker_bee/middleware/cloud_stack_api_spec.rb b/spec/units/stacker_bee/middleware/cloud_stack_api_spec.rb
index 22872d7..b312b2c 100644
--- a/spec/units/stacker_bee/middleware/cloud_stack_api_spec.rb
+++ b/spec/units/stacker_bee/middleware/cloud_stack_api_spec.rb
@@ -1,12 +1,11 @@
describe StackerBee::Middleware::CloudStackAPI do
let(:env) do
StackerBee::Middleware::Environment.new(
- endpoint_name: 'endpoint-name',
- path: path
+ endpoint_name: 'endpoint-name'
)
end
- let(:middleware) { described_class.new(api_key: 'API-KEY', params: {}) }
- let(:path) { nil }
+ let(:middleware) { described_class.new(api_key: 'API-KEY', url: url) }
+ let(:url) { 'http://localhost:1234/my/path' }
before do
middleware.before(env)
@@ -15,15 +14,7 @@
describe 'request' do
subject { env.request }
- context 'when the path is not set' do
- let(:path) { nil }
- its(:path) { should == described_class::DEFAULT_PATH }
- end
-
- context 'when the path is already set' do
- let(:path) { 'already set' }
- its(:path) { should == path }
- end
+ its(:path) { should == '/my/path' }
end
describe 'params' do