saddle 0.0.23 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
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