saddle 0.0.19 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/saddle/endpoint.rb +64 -31
- data/lib/saddle/method_tree_builder.rb +4 -6
- data/lib/saddle/middleware/request/retry.rb +1 -1
- data/lib/saddle/options.rb +13 -7
- data/lib/saddle/requester.rb +14 -14
- data/lib/saddle/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTdiMWYwODYzZTI0YzdiZGViNWU3MTJhMGFjZmIwMjcxYzcyNmFmMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjBiMTU3YWY3YjE2OGYzYzVkN2JmNTQ5OWNmZDhiYTFmZWE4MDhkMA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MmUzMzE3Y2ExOGM2ZDc1OGQ4M2ZmYTU3ODUxMTE4MTJhNDY4NDY0ZDY2M2Yw
|
10
|
+
ZTM0MDk3YmJlMDYyYWI4ZTFiMDY4YzM5OTBiZWU4NGNiY2VkYzJiYzM3ODI5
|
11
|
+
MDUzYzUxZTNmYjk1Zjk0NDFhNmIzNzhmYWM4NGNkMzlmMTg2ZTA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjMxNjBiODUyNjNkZjZmNGMyYTU2MTg2MTVhOWUxOTFmMWRhOTdiNDM2NWY2
|
14
|
+
YjNmMDA5NzM3N2I2Nzc1M2ViNzZiMGQ0YjU0ZWFiNzk0YWQ2ODYzNmZkYjRm
|
15
|
+
ZDg4Mjc1ZWRlYzc2MDU2MjczMmZlMjU4YTFlZTE1OTg5ZWY1YjE=
|
data/lib/saddle/endpoint.rb
CHANGED
@@ -14,68 +14,94 @@ module Saddle
|
|
14
14
|
attr_reader :requester, :relative_path, :parent
|
15
15
|
|
16
16
|
# Each endpoint needs to have a requester in order to ... make ... uh ... requests.
|
17
|
-
def initialize(requester,
|
17
|
+
def initialize(requester, relative_path_override=nil, parent=nil)
|
18
18
|
@requester = requester
|
19
|
-
@relative_path = relative_path
|
20
19
|
@parent = parent
|
20
|
+
@relative_path = relative_path_override || _relative_path()
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
23
|
# Provide GET functionality for the implementer class
|
25
24
|
def get(action, params={}, options={})
|
26
|
-
|
25
|
+
_request(:get, action, params, options)
|
27
26
|
end
|
28
27
|
|
29
28
|
# Provide POST functionality for the implementer class
|
30
29
|
def post(action, params={}, options={})
|
31
|
-
|
30
|
+
_request(:post, action, params, options)
|
32
31
|
end
|
33
32
|
|
34
33
|
# Provide PUT functionality for the implementer class
|
35
34
|
def put(action, params={}, options={})
|
36
|
-
|
35
|
+
_request(:put, action, params, options)
|
37
36
|
end
|
38
37
|
|
39
38
|
# Provide DELETE functionality for the implementer class
|
40
39
|
def delete(action, params={}, options={})
|
41
|
-
|
40
|
+
_request(:delete, action, params, options)
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# This will create a resource endpoint, based upon the parameters
|
45
|
+
# of this current node endpoint
|
46
|
+
def create_resource_endpoint(endpoint_class, resource_id)
|
47
|
+
endpoint_class.new(@requester, resource_id, self)
|
42
48
|
end
|
43
49
|
|
44
|
-
|
50
|
+
|
51
|
+
# Create an endpoint instance and foist it upon this node
|
52
|
+
# Not private, but not part of the public interface for an endpoint
|
53
|
+
def _build_and_attach_node(endpoint_class, method_name=nil)
|
54
|
+
# Create the new endpoint
|
55
|
+
endpoint_instance = endpoint_class.new(@requester, method_name, self)
|
56
|
+
# Attach the endpoint as an instance variable and method
|
57
|
+
method_name ||= ActiveSupport::Inflector.underscore(
|
58
|
+
ActiveSupport::Inflector.demodulize(
|
59
|
+
endpoint_class.name
|
60
|
+
)
|
61
|
+
)
|
62
|
+
self.instance_variable_set("@#{method_name}", endpoint_instance)
|
63
|
+
self.class.class_eval { define_method(method_name) { endpoint_instance } }
|
64
|
+
endpoint_instance
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def _request(method, action, params={}, options={})
|
45
71
|
# Augment in interesting options
|
46
72
|
options[:saddle] = {
|
47
|
-
:client_name =>
|
48
|
-
:call_chain =>
|
73
|
+
:client_name => _client_name(),
|
74
|
+
:call_chain => _path_array(),
|
49
75
|
:action => action,
|
50
76
|
}
|
51
|
-
@requester.send(method,
|
77
|
+
@requester.send(method, _path(action), params, options)
|
52
78
|
end
|
53
79
|
|
54
80
|
|
55
81
|
# Get the url path for this endpoint/action combo
|
56
|
-
def
|
57
|
-
paths =
|
82
|
+
def _path(action=nil)
|
83
|
+
paths = _path_array()
|
58
84
|
paths << action unless action.nil?
|
59
85
|
'/' + paths.join('/')
|
60
86
|
end
|
61
87
|
|
62
|
-
def
|
63
|
-
|
88
|
+
def _path_array
|
89
|
+
_endpoint_chain().map(&:relative_path).reject{|p| p.nil?}
|
64
90
|
end
|
65
91
|
|
66
92
|
# Get the parent chain that led to this endpoint
|
67
|
-
def
|
93
|
+
def _endpoint_chain
|
68
94
|
chain = []
|
69
95
|
node = self
|
70
96
|
while node.is_a?(BaseEndpoint)
|
71
97
|
chain << node
|
72
98
|
node = node.parent
|
73
99
|
end
|
74
|
-
chain.reverse
|
100
|
+
chain.reverse()
|
75
101
|
end
|
76
102
|
|
77
103
|
# Traverse back until we find the original client
|
78
|
-
def
|
104
|
+
def _client
|
79
105
|
node = self
|
80
106
|
while node.is_a?(BaseEndpoint)
|
81
107
|
node = node.parent
|
@@ -84,23 +110,30 @@ module Saddle
|
|
84
110
|
end
|
85
111
|
|
86
112
|
# Underscore name of the client
|
87
|
-
def
|
88
|
-
ActiveSupport::Inflector.underscore(self.
|
113
|
+
def _client_name
|
114
|
+
ActiveSupport::Inflector.underscore(self._client.name.split('::')[-2])
|
89
115
|
end
|
90
116
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
endpoint_instance = endpoint_class.new(@requester, method_name, self)
|
95
|
-
self.instance_variable_set("@#{method_name}", endpoint_instance)
|
96
|
-
self.class.class_eval { define_method(method_name) { endpoint_instance } }
|
97
|
-
endpoint_instance
|
117
|
+
# If the parent is not an endpoint, it is a root node
|
118
|
+
def _is_root?
|
119
|
+
!@parent.is_a?(BaseEndpoint)
|
98
120
|
end
|
99
121
|
|
100
|
-
#
|
101
|
-
#
|
102
|
-
|
103
|
-
|
122
|
+
# Build the default relative path for this endpoint node
|
123
|
+
# If this is a root node, use nil.
|
124
|
+
# Otherwise use the underscored version of the class name
|
125
|
+
#
|
126
|
+
# Override this if needed for specific endpoints
|
127
|
+
def _relative_path
|
128
|
+
if _is_root?
|
129
|
+
nil
|
130
|
+
else
|
131
|
+
ActiveSupport::Inflector.underscore(
|
132
|
+
ActiveSupport::Inflector.demodulize(
|
133
|
+
self.class.name
|
134
|
+
)
|
135
|
+
)
|
136
|
+
end
|
104
137
|
end
|
105
138
|
end
|
106
139
|
|
@@ -36,6 +36,7 @@ module Saddle
|
|
36
36
|
if File.file?(root_endpoint_file)
|
37
37
|
# Load it and create our base endpoint
|
38
38
|
load(root_endpoint_file)
|
39
|
+
# RootEndpoint is the special class name for a root endpoint
|
39
40
|
root_node_class = self.implementation_module::RootEndpoint
|
40
41
|
else
|
41
42
|
# 'root_endpoint.rb' doesn't exist, so create a dummy endpoint
|
@@ -57,7 +58,7 @@ module Saddle
|
|
57
58
|
if const.class == Module
|
58
59
|
# A module means that it's a branch
|
59
60
|
# Build the branch out with a base endpoint
|
60
|
-
branch_node = current_node.
|
61
|
+
branch_node = current_node._build_and_attach_node(
|
61
62
|
Saddle::BaseEndpoint,
|
62
63
|
ActiveSupport::Inflector.underscore(const_symbol)
|
63
64
|
)
|
@@ -68,10 +69,7 @@ module Saddle
|
|
68
69
|
if const < Saddle::TraversalEndpoint
|
69
70
|
# A class means that it's a node
|
70
71
|
# Build out this endpoint on the current node
|
71
|
-
current_node.
|
72
|
-
const,
|
73
|
-
ActiveSupport::Inflector.underscore(const_symbol)
|
74
|
-
)
|
72
|
+
current_node._build_and_attach_node(const)
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
@@ -98,7 +96,7 @@ module Saddle
|
|
98
96
|
end
|
99
97
|
|
100
98
|
# If this client was not fully constructed, it may not even have an
|
101
|
-
# implementation root. Allow that behavior
|
99
|
+
# implementation root. Allow that behavior to avoid filesystem searching.
|
102
100
|
def knows_root?
|
103
101
|
defined?(self.implementation_root)
|
104
102
|
end
|
@@ -18,7 +18,7 @@ module Saddle
|
|
18
18
|
|
19
19
|
def call(env)
|
20
20
|
retries = env[:request][:num_retries] || 2
|
21
|
-
backoff = env[:request][:retry_backoff] || 0.050 #
|
21
|
+
backoff = env[:request][:retry_backoff] || 0.050 # in seconds
|
22
22
|
begin
|
23
23
|
@app.call(self.class.deep_copy(env))
|
24
24
|
rescue => e
|
data/lib/saddle/options.rb
CHANGED
@@ -7,14 +7,15 @@ module Saddle
|
|
7
7
|
# Construct our default options, based upon the class methods
|
8
8
|
def default_options
|
9
9
|
{
|
10
|
-
:host => host,
|
11
|
-
:port => port,
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
10
|
+
:host => host(),
|
11
|
+
:port => port(),
|
12
|
+
:path_prefix => path_prefix(),
|
13
|
+
:use_ssl => use_ssl(),
|
14
|
+
:request_style => request_style(),
|
15
|
+
:num_retries => num_retries(),
|
16
|
+
:timeout => timeout(),
|
16
17
|
:additional_middlewares => self.additional_middlewares,
|
17
|
-
:stubs => stubs,
|
18
|
+
:stubs => stubs(),
|
18
19
|
}
|
19
20
|
end
|
20
21
|
|
@@ -28,6 +29,11 @@ module Saddle
|
|
28
29
|
80
|
29
30
|
end
|
30
31
|
|
32
|
+
# A string prefix to prepend to paths as they are build (ie, 'v1')
|
33
|
+
def path_prefix
|
34
|
+
''
|
35
|
+
end
|
36
|
+
|
31
37
|
# Should this client use SSL by default?
|
32
38
|
def use_ssl
|
33
39
|
false
|
data/lib/saddle/requester.rb
CHANGED
@@ -34,6 +34,8 @@ module Saddle
|
|
34
34
|
raise ':host must be a string' unless @host.is_a?(String)
|
35
35
|
@port = opt[:port] || 80
|
36
36
|
raise ':port must be an integer' unless @port.is_a?(Fixnum)
|
37
|
+
@path_prefix = opt[:path_prefix] || ''
|
38
|
+
raise ':path_prefix must be a string' unless @path_prefix.is_a?(String)
|
37
39
|
@use_ssl = opt[:use_ssl] || false
|
38
40
|
raise ':use_ssl must be true or false' unless (@use_ssl.is_a?(TrueClass) || @use_ssl.is_a?(FalseClass))
|
39
41
|
@request_style = opt[:request_style] || :json
|
@@ -41,9 +43,7 @@ module Saddle
|
|
41
43
|
@num_retries = opt[:num_retries] || 3
|
42
44
|
raise ':num_retries must be an integer' unless @num_retries.is_a?(Fixnum)
|
43
45
|
@timeout = opt[:timeout]
|
44
|
-
unless @timeout.nil?
|
45
|
-
raise ':timeout must be a number or nil' unless @timeout.is_a?(Numeric)
|
46
|
-
end
|
46
|
+
raise ':timeout must be nil or an integer' unless (@timeout.nil? || @timeout.is_a?(Numeric))
|
47
47
|
@additional_middlewares = opt[:additional_middlewares] || []
|
48
48
|
raise ':additional_middleware must be an Array' unless @additional_middlewares.is_a?(Array)
|
49
49
|
raise 'invalid middleware found' unless @additional_middlewares.all? { |m| m[:klass] < Faraday::Middleware }
|
@@ -99,7 +99,7 @@ module Saddle
|
|
99
99
|
|
100
100
|
# Construct a base url using this requester's settings
|
101
101
|
def base_url
|
102
|
-
"http#{'s' if @use_ssl}://#{@host}:#{@port}"
|
102
|
+
"http#{'s' if @use_ssl}://#{@host}:#{@port}/#{@path_prefix}"
|
103
103
|
end
|
104
104
|
|
105
105
|
# Build a connection instance, wrapped in the middleware that we want
|
@@ -113,36 +113,36 @@ module Saddle
|
|
113
113
|
end
|
114
114
|
|
115
115
|
# Support default return values upon exception
|
116
|
-
builder.use
|
116
|
+
builder.use(Saddle::Middleware::Response::DefaultResponse)
|
117
117
|
|
118
118
|
# Apply additional implementation-specific middlewares
|
119
119
|
@additional_middlewares.each do |m|
|
120
|
-
builder.use
|
120
|
+
builder.use(m[:klass], *m[:args])
|
121
121
|
end
|
122
122
|
|
123
123
|
# Hard timeout on the entire request
|
124
|
-
builder.use
|
124
|
+
builder.use(Saddle::Middleware::RubyTimeout)
|
125
125
|
|
126
126
|
# Request encoding
|
127
|
-
builder.use
|
128
|
-
builder.use
|
127
|
+
builder.use(Saddle::Middleware::Request::JsonEncoded)
|
128
|
+
builder.use(Saddle::Middleware::Request::UrlEncoded)
|
129
129
|
|
130
130
|
# Automatic retries
|
131
|
-
builder.use
|
131
|
+
builder.use(Saddle::Middleware::Request::Retry)
|
132
132
|
|
133
133
|
# Handle parsing out the response if it's JSON
|
134
|
-
builder.use
|
134
|
+
builder.use(Saddle::Middleware::Response::ParseJson)
|
135
135
|
|
136
136
|
# Raise exceptions on 4xx and 5xx errors
|
137
|
-
builder.use
|
137
|
+
builder.use(Faraday::Response::RaiseError)
|
138
138
|
|
139
139
|
# Set up our adapter
|
140
140
|
if @stubs.nil?
|
141
141
|
# Use the default adapter
|
142
|
-
builder.adapter
|
142
|
+
builder.adapter(:net_http)
|
143
143
|
else
|
144
144
|
# Use the test adapter
|
145
|
-
builder.adapter
|
145
|
+
builder.adapter(:test, @stubs)
|
146
146
|
end
|
147
147
|
end
|
148
148
|
end
|
data/lib/saddle/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Lewis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|