saddle 0.0.23 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWZjMDk3MDczMTlkYjllMDk3MmQ2NDRlNWY1ODE3Yjk5NTFiNmQ0Mw==
4
+ Y2Y4MDY5M2RmMWE1MDEwYWZiY2IzYWI2ZWFjNTJkNzYzZGIwYWU4Ng==
5
5
  data.tar.gz: !binary |-
6
- ODlkYTE3OGJhNjU3Mjc3ODUwYmVjODEyNWRhMzNlMTA0MzczOGEzZQ==
6
+ MTI2M2QxZjMzNzMyZjYxOTFhZDAxNDc0YWJlYTBlZDQ3ODBmOTVjZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTY1MTFiZmIxYTIyOWZhNWZhZGY5ZTA5NTE5ZDdjMWExOGNmNGU0M2Q5ODUx
10
- NjFjYzM0MjFhOGVjNjkxZTYyYTkyMzc0MTY2YTEzYzBiMDVlYTAyMTBlMmEz
11
- OTdlNjc0OWFmNGU4OWVhMTY5MTg0ODUzODBiM2JlNTY5M2U2MzI=
9
+ ZTIzNjk2ZWZjYzJjNzE4YzVhMTNkYWM1YjliNGUxZjM4MjE1ZTNhMjAxMGM3
10
+ ZjJiZDJjYTllZjNhMGUwMzkwYTNlMjhmODY2ODU0M2M5MDIyMTM3NTk4MjBm
11
+ Y2RjZTBiMzY1NmM5MWJiNzkzNGE2ODAyNjE3ODc0Y2E5MzQzMmI=
12
12
  data.tar.gz: !binary |-
13
- Y2QyNTVjMjllZGY3MTlmYjI5NmQ2ZDYzODhmM2ZkYmFjYmNkN2RjYjljNjc3
14
- MjdmYjc5ZDE1N2MyM2Q2ZDRkMDVhMzhiM2RmNjhkOWZiM2U5ODRlMGQ1MTM2
15
- NDkyYzFlZTE1M2IyYjZlZTRhY2M1NGUxYWUwMGQ1ODk5OGZhZmE=
13
+ YTE3YjBhYTBlMzQxNDdiMTQ4NTM0NzY3NzE5MWU2OTg2MjJhYjk5NzQyNDZk
14
+ YWJkN2ZhZGI2OGIyYmE3OTRhM2E3OTQyYmU0Yzk3NWRlMzE1M2U3MjMzYjY1
15
+ YTAzOWI2MDQxZGUxNTY2YmZmYTUyZDE2NDkyOTQ1MDQ2OTg2NWE=
data/lib/saddle.rb CHANGED
@@ -17,28 +17,36 @@ module Saddle
17
17
 
18
18
  class << self
19
19
  attr_accessor :additional_middlewares
20
- end
21
20
 
22
- # Once your implementation is written, this is the magic you need to
23
- # create a client instance.
24
- def self.create(opt={})
25
- self.build_tree(
26
- Saddle::Requester.new(
27
- default_options.merge(opt)
21
+ # Once your implementation is written, this is the magic you need to
22
+ # create a client instance.
23
+ def create(opt={})
24
+ self.build_tree(
25
+ Saddle::Requester.new(
26
+ self,
27
+ default_options.merge(opt)
28
+ )
28
29
  )
29
- )
30
- end
30
+ end
31
31
 
32
- def self.inherited(obj)
33
- # Clone the parent's additional_middlewares
34
- obj.additional_middlewares = if defined?(obj.superclass.additional_middlewares)
35
- (obj.superclass.additional_middlewares || []).clone
36
- else
37
- []
32
+ def inherited(obj)
33
+ # Clone the parent's additional_middlewares
34
+ obj.additional_middlewares = if defined?(obj.superclass.additional_middlewares)
35
+ (obj.superclass.additional_middlewares || []).clone
36
+ else
37
+ []
38
+ end
39
+ # Add additional client attributes
40
+ obj.send(:include, Saddle::ClientAttributes)
38
41
  end
39
- # Add additional client attributes
40
- obj.send(:include, Saddle::ClientAttributes)
41
- end
42
+
43
+ # Name of the module that contains the implementing client
44
+ def root_namespace
45
+ module_nests = self.name.split('::')
46
+ module_nests.length > 1 ? module_nests[-2] : module_nests.last
47
+ end
48
+
49
+ end
42
50
 
43
51
  end
44
52
 
@@ -69,8 +69,8 @@ module Saddle
69
69
 
70
70
  def _request(method, action, params={}, options={})
71
71
  # Augment in interesting options
72
+ options[:saddle] ||= {}
72
73
  options[:saddle] = {
73
- :client_name => _client_name(),
74
74
  :call_chain => _path_array(),
75
75
  :action => action,
76
76
  }
@@ -100,20 +100,6 @@ module Saddle
100
100
  chain.reverse()
101
101
  end
102
102
 
103
- # Traverse back until we find the original client
104
- def _client
105
- node = self
106
- while node.is_a?(BaseEndpoint)
107
- node = node.parent
108
- end
109
- node
110
- end
111
-
112
- # Underscore name of the client
113
- def _client_name
114
- ActiveSupport::Inflector.underscore(self._client.name.split('::')[-2])
115
- end
116
-
117
103
  # If the parent is not an endpoint, it is a root node
118
104
  def _is_root?
119
105
  !@parent.is_a?(BaseEndpoint)
@@ -40,11 +40,11 @@ module Saddle
40
40
  root_node_class = self.implementation_module::RootEndpoint
41
41
  else
42
42
  # 'root_endpoint.rb' doesn't exist, so create a dummy endpoint
43
- root_node_class = Saddle::BaseEndpoint
43
+ root_node_class = Saddle::TraversalEndpoint
44
44
  end
45
45
  else
46
46
  # we don't even have an implementation root, so create a dummy endpoint
47
- root_node_class = Saddle::BaseEndpoint
47
+ root_node_class = Saddle::TraversalEndpoint
48
48
  end
49
49
  root_node_class.new(requester, nil, self)
50
50
  end
@@ -59,7 +59,7 @@ module Saddle
59
59
  # A module means that it's a branch
60
60
  # Build the branch out with a base endpoint
61
61
  branch_node = current_node._build_and_attach_node(
62
- Saddle::BaseEndpoint,
62
+ Saddle::TraversalEndpoint,
63
63
  ActiveSupport::Inflector.underscore(const_symbol)
64
64
  )
65
65
  # Build out the branch's endpoints on the new branch node
@@ -34,17 +34,21 @@ module Saddle
34
34
  if env[:request][:statsd_path]
35
35
  statsd_path = env[:request][:statsd_path]
36
36
  elsif env[:request][:saddle]
37
- statsd_path = (
38
- ['saddle'] +
39
- [env[:request][:saddle][:client_name]] +
40
- env[:request][:saddle][:call_chain] +
41
- [env[:request][:saddle][:action]]
42
- ).join('.')
43
- else
44
- statsd_path = "saddle.raw.#{env[:host].to_s}.#{env[:path].to_s}"
37
+ statsd_path_components = [
38
+ 'saddle',
39
+ ActiveSupport::Inflector.underscore(env[:request][:saddle][:client].name),
40
+ ]
41
+ if env[:request][:saddle][:call_chain] && env[:request][:saddle][:action]
42
+ statsd_path_components += env[:request][:saddle][:call_chain]
43
+ statsd_path_components << env[:request][:saddle][:action]
44
+ else
45
+ statsd_path_components << 'raw'
46
+ statsd_path_components << "#{env[:url].host}#{env[:url].path}"
47
+ end
48
+ statsd_path = statsd_path_components.join('.')
45
49
  end
46
50
 
47
- # If we have a path, wrap the ensuing app call in STATSD timing
51
+ # If we have a path, wrap the call
48
52
  if statsd_path
49
53
  self.statsd.time(statsd_path) do
50
54
  @app.call(env)
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+
3
+
4
+
5
+ module Saddle
6
+ module Middleware
7
+ module Request
8
+
9
+ # Public: Adds a prefix to the relative url path if present
10
+
11
+ class PathPrefix < Faraday::Middleware
12
+ def call(env)
13
+ if env[:request][:client_options][:path_prefix]
14
+ env[:url].path = "/#{env[:request][:client_options][:path_prefix]}#{env[:url].path}"
15
+ end
16
+
17
+ @app.call env
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -26,12 +26,12 @@ module Saddle
26
26
 
27
27
  # The default port for this client
28
28
  def port
29
- 80
29
+ nil
30
30
  end
31
31
 
32
32
  # A string prefix to prepend to paths as they are build (ie, 'v1')
33
33
  def path_prefix
34
- ''
34
+ nil
35
35
  end
36
36
 
37
37
  # Should this client use SSL by default?
@@ -55,6 +55,14 @@ module Saddle
55
55
  30
56
56
  end
57
57
 
58
+ # If you want to set up an ActiveSupport::Notification, give your client
59
+ # an instrumentation key to monitor.
60
+ def instrumentation_key
61
+ nil
62
+ end
63
+
64
+
65
+
58
66
  # Use this to add additional middleware to the request stack
59
67
  # ex:
60
68
  # add_middleware({
@@ -2,6 +2,7 @@ require 'faraday'
2
2
  require 'faraday_middleware'
3
3
 
4
4
  require 'saddle/middleware/request/encode_json'
5
+ require 'saddle/middleware/request/path_prefix'
5
6
  require 'saddle/middleware/request/retry'
6
7
  require 'saddle/middleware/request/url_encoded'
7
8
  require 'saddle/middleware/response/default_response'
@@ -21,7 +22,7 @@ module Saddle
21
22
 
22
23
  # Available options
23
24
  ## host - host to connect to (default: localhost)
24
- ## port - port to connect on (default: 80)
25
+ ## port - port to connect on
25
26
  ## use_ssl - true if we should use https (default: false)
26
27
  ## request_style - :json or :urlencoded (default: :json)
27
28
  ## num_retries - number of times to retry each request (default: 3)
@@ -29,15 +30,15 @@ module Saddle
29
30
  ## additional_middleware - an Array of more middlewares to apply to the top of the stack
30
31
  ## - each middleware consists of hash of klass, and optionally args (an array)
31
32
  ## stubs - test stubs for specs
32
- def initialize(opt={})
33
+ def initialize(parent_client, opt={})
34
+ # We may want properties about the parent client in middlewares
35
+ @parent_client = parent_client
33
36
  # Store the options for later use
34
37
  @options = opt
35
38
  @host = opt[:host] || 'localhost'
36
39
  raise ':host must be a string' unless @host.is_a?(String)
37
- @port = opt[:port] || 80
38
- raise ':port must be an integer' unless @port.is_a?(Fixnum)
39
- @path_prefix = opt[:path_prefix] || ''
40
- raise ':path_prefix must be a string' unless @path_prefix.is_a?(String)
40
+ @port = opt[:port]
41
+ raise ':port must be nil or an integer' unless (@port.nil? || @port.is_a?(Fixnum))
41
42
  @use_ssl = opt[:use_ssl] || false
42
43
  raise ':use_ssl must be true or false' unless (@use_ssl.is_a?(TrueClass) || @use_ssl.is_a?(FalseClass))
43
44
  @request_style = opt[:request_style] || :json
@@ -101,7 +102,7 @@ module Saddle
101
102
 
102
103
  # Construct a base url using this requester's settings
103
104
  def base_url
104
- "http#{'s' if @use_ssl}://#{@host}:#{@port}/#{@path_prefix}"
105
+ "http#{'s' if @use_ssl}://#{@host}#{":#{@port}" if @port}"
105
106
  end
106
107
 
107
108
  # Build a connection instance, wrapped in the middleware that we want
@@ -110,6 +111,11 @@ module Saddle
110
111
  # Include the requester level options
111
112
  builder.options[:client_options] = @options
112
113
 
114
+ # Include a saddle hash
115
+ builder.options[:saddle] = {
116
+ :client => @parent_client,
117
+ }
118
+
113
119
  # Config options
114
120
  unless @timeout.nil?
115
121
  builder.options[:timeout] = @timeout
@@ -117,6 +123,12 @@ module Saddle
117
123
  builder.options[:num_retries] = @num_retries
118
124
  end
119
125
 
126
+ # Set up a user agent (named for the client's namespace)
127
+ builder.headers[:user_agent] = @parent_client.root_namespace
128
+
129
+ # Set up the path prefix if needed
130
+ builder.use(Saddle::Middleware::Request::PathPrefix)
131
+
120
132
  # Support default return values upon exception
121
133
  builder.use(Saddle::Middleware::Response::DefaultResponse)
122
134
 
@@ -141,6 +153,9 @@ module Saddle
141
153
  # Raise exceptions on 4xx and 5xx errors
142
154
  builder.use(Faraday::Response::RaiseError)
143
155
 
156
+ # Set up instrumentation around the adapter for extensibility
157
+ builder.use(FaradayMiddleware::Instrumentation)
158
+
144
159
  # Set up our adapter
145
160
  if @stubs.nil?
146
161
  # Use the default adapter
@@ -1,3 +1,3 @@
1
1
  module Saddle
2
- VERSION = '0.0.23'
2
+ VERSION = '0.0.25'
3
3
  end
@@ -0,0 +1,32 @@
1
+ require 'saddle'
2
+ require 'saddle/middleware/logging/airbrake'
3
+
4
+
5
+
6
+ describe Saddle::Middleware::Logging::AirbrakeLogger do
7
+
8
+ context "test Airbrake middleware" do
9
+
10
+ it "with a request" do
11
+ class AirbrakeClient < Saddle::Client
12
+ add_middleware({
13
+ :klass => Saddle::Middleware::Logging::AirbrakeLogger,
14
+ })
15
+ end
16
+
17
+ client = AirbrakeClient.create(
18
+ :stubs => Faraday::Adapter::Test::Stubs.new do |stub|
19
+ stub.get('/test') {
20
+ [
21
+ 200,
22
+ {},
23
+ 'Party on!',
24
+ ]
25
+ }
26
+ end
27
+ )
28
+ client.requester.get('/test').should == 'Party on!'
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ require 'saddle'
2
+
3
+
4
+
5
+ describe 'FaradayMiddleware::Instrumentation' do
6
+
7
+ context "test integration of instrumentation middleware" do
8
+
9
+ it "with a request" do
10
+ client = Saddle::Client.create(
11
+ :stubs => Faraday::Adapter::Test::Stubs.new do |stub|
12
+ stub.get('/test') {
13
+ [
14
+ 200,
15
+ {},
16
+ 'Party on!',
17
+ ]
18
+ }
19
+ end
20
+ )
21
+
22
+
23
+
24
+
25
+ client.requester.get('/test').should == 'Party on!'
26
+ end
27
+
28
+ end
29
+ end
@@ -1,5 +1,7 @@
1
1
  require 'saddle'
2
2
 
3
+
4
+
3
5
  describe Saddle::Client do
4
6
 
5
7
  context "retry requests" do
@@ -0,0 +1,33 @@
1
+ require 'saddle'
2
+ require 'saddle/middleware/logging/statsd'
3
+
4
+
5
+
6
+ describe Saddle::Middleware::Logging::StatsdLogger do
7
+
8
+ context "test Statsd middleware" do
9
+
10
+ it "with a request" do
11
+ class StatsdClient < Saddle::Client
12
+ add_middleware({
13
+ :klass => Saddle::Middleware::Logging::StatsdLogger,
14
+ :args => ['127.0.0.1'],
15
+ })
16
+ end
17
+
18
+ client = StatsdClient.create(
19
+ :stubs => Faraday::Adapter::Test::Stubs.new do |stub|
20
+ stub.get('/test') {
21
+ [
22
+ 200,
23
+ {},
24
+ 'Party on!',
25
+ ]
26
+ }
27
+ end
28
+ )
29
+ client.requester.get('/test').should == 'Party on!'
30
+ end
31
+
32
+ end
33
+ end
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.23
4
+ version: 0.0.25
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-19 00:00:00.000000000 Z
11
+ date: 2013-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -72,6 +72,7 @@ files:
72
72
  - lib/saddle/middleware/logging/airbrake.rb
73
73
  - lib/saddle/middleware/logging/statsd.rb
74
74
  - lib/saddle/middleware/request/encode_json.rb
75
+ - lib/saddle/middleware/request/path_prefix.rb
75
76
  - lib/saddle/middleware/request/retry.rb
76
77
  - lib/saddle/middleware/request/url_encoded.rb
77
78
  - lib/saddle/middleware/response/default_response.rb
@@ -81,11 +82,13 @@ files:
81
82
  - lib/saddle/requester.rb
82
83
  - lib/saddle/version.rb
83
84
  - saddle.gemspec
84
- - spec/middleware_spec.rb
85
+ - spec/middleware/airbrake_spec.rb
86
+ - spec/middleware/instrumentation_spec.rb
87
+ - spec/middleware/retry_spec.rb
88
+ - spec/middleware/statsd_spec.rb
85
89
  - spec/multiple_spec.rb
86
90
  - spec/requester/get_spec.rb
87
91
  - spec/requester/post_spec.rb
88
- - spec/requester/retry_spec.rb
89
92
  homepage: https://github.com/mLewisLogic/saddle
90
93
  licenses:
91
94
  - MIT
@@ -112,8 +115,10 @@ specification_version: 4
112
115
  summary: A full-featured, generic consumer layer for you to build API client implementations
113
116
  with.
114
117
  test_files:
115
- - spec/middleware_spec.rb
118
+ - spec/middleware/airbrake_spec.rb
119
+ - spec/middleware/instrumentation_spec.rb
120
+ - spec/middleware/retry_spec.rb
121
+ - spec/middleware/statsd_spec.rb
116
122
  - spec/multiple_spec.rb
117
123
  - spec/requester/get_spec.rb
118
124
  - spec/requester/post_spec.rb
119
- - spec/requester/retry_spec.rb
@@ -1,48 +0,0 @@
1
- require 'saddle'
2
- require 'saddle/middleware/logging/airbrake'
3
- require 'saddle/middleware/logging/statsd'
4
-
5
- describe Saddle::Client do
6
-
7
- context "Test middlewares" do
8
-
9
- before :each do
10
- @stubs = Faraday::Adapter::Test::Stubs.new do |stub|
11
- stub.get('/test') {
12
- [
13
- 200,
14
- {},
15
- 'Party on!',
16
- ]
17
- }
18
- end
19
-
20
- @default_client = Saddle::Client.create(:stubs => @stubs)
21
- end
22
-
23
-
24
- it "test logging/airbrake" do
25
- class AirbrakeClient < Saddle::Client
26
- add_middleware({
27
- :klass => Saddle::Middleware::Logging::AirbrakeLogger,
28
- })
29
- end
30
-
31
- client = AirbrakeClient.create(:stubs => @stubs)
32
- client.requester.get('/test').should == 'Party on!'
33
- end
34
-
35
- it "test logging/statsd" do
36
- class StatsdClient < Saddle::Client
37
- add_middleware({
38
- :klass => Saddle::Middleware::Logging::StatsdLogger,
39
- :args => ['127.0.0.1'],
40
- })
41
- end
42
-
43
- client = StatsdClient.create(:stubs => @stubs)
44
- client.requester.get('/test').should == 'Party on!'
45
- end
46
-
47
- end
48
- end