LVS-JSONService 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.specification +1 -1
- data/JSONService.gemspec +7 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/lvs/json_service/connection_manager.rb +53 -0
- data/lib/lvs/json_service/request.rb +26 -25
- data/spec/lvs/json_service/connection_manager_spec.rb +294 -0
- data/spec/lvs/json_service/json_methods_spec.rb +57 -0
- data/spec/lvs/json_service/mock_net_http.rb +17 -0
- data/spec/lvs/json_service/request_spec.rb +4 -18
- data/spec/lvs/json_service/setting_fields_spec.rb +24 -0
- metadata +9 -2
data/.specification
CHANGED
data/JSONService.gemspec
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{JSONService}
|
5
|
-
s.version = "0.3.
|
5
|
+
s.version = "0.3.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["LVS"]
|
8
|
+
s.authors = ["LVS", "andyjeffries"]
|
9
9
|
s.date = %q{2009-08-06}
|
10
10
|
s.email = %q{info@lvs.co.uk}
|
11
11
|
s.extra_rdoc_files = [
|
@@ -24,12 +24,17 @@ Gem::Specification.new do |s|
|
|
24
24
|
"lib/lvs/json_service/base.rb",
|
25
25
|
"lib/lvs/json_service/logger.rb",
|
26
26
|
"lib/lvs/json_service/request.rb",
|
27
|
+
"lib/lvs/json_service/connection_manager.rb",
|
27
28
|
"spec/fixtures/error_response.yml",
|
28
29
|
"spec/fixtures/response.yml",
|
29
30
|
"spec/json_service_spec.rb",
|
30
31
|
"spec/lvs/json_service/base_spec.rb",
|
32
|
+
"spec/lvs/json_service/connection_manager_spec.rb",
|
33
|
+
"spec/lvs/json_service/json_methods_spec.rb",
|
31
34
|
"spec/lvs/json_service/logger_spec.rb",
|
32
35
|
"spec/lvs/json_service/request_spec.rb",
|
36
|
+
"spec/lvs/json_service/mock_net_http.rb",
|
37
|
+
"spec/lvs/json_service/setting_fields_spec.rb",
|
33
38
|
"spec/spec.opts",
|
34
39
|
"spec/spec_helper.rb"
|
35
40
|
]
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ begin
|
|
8
8
|
gem.summary = %Q{TODO}
|
9
9
|
gem.email = "info@lvs.co.uk"
|
10
10
|
gem.homepage = "http://github.com/lvs/JSONService"
|
11
|
-
gem.authors = ["LVS"]
|
11
|
+
gem.authors = ["LVS", "andyjeffries"]
|
12
12
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
13
|
end
|
14
14
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module LVS
|
2
|
+
module JsonService
|
3
|
+
class ConnectionManager
|
4
|
+
def self.get_connection(host, port, options)
|
5
|
+
@@connections ||= {}
|
6
|
+
key = create_key(host, port, options)
|
7
|
+
connection = @@connections[key]
|
8
|
+
if connection.nil? || !connection.started?
|
9
|
+
connection = create_connection(host, port, options)
|
10
|
+
@@connections[key] = connection
|
11
|
+
end
|
12
|
+
connection
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reset_connection(host, port, options)
|
16
|
+
@@connections ||= {}
|
17
|
+
key = create_key(host, port, options)
|
18
|
+
@@connections.delete(key)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.reset_all_connections
|
22
|
+
@@connections = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create_connection(host, port, options)
|
26
|
+
http = Net::HTTP.new(host, port)
|
27
|
+
if options[:encrypted]
|
28
|
+
http.use_ssl = true
|
29
|
+
# Self-signed certs give streams of "warning: peer certificate won't be verified in this SSL session"
|
30
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
31
|
+
LVS::JsonService::Logger.debug "Using SSL"
|
32
|
+
if options[:auth_cert]
|
33
|
+
LVS::JsonService::Logger.debug "Using Auth"
|
34
|
+
http.cert = OpenSSL::X509::Certificate.new(File.read(options[:auth_cert]))
|
35
|
+
http.key = OpenSSL::PKey::RSA.new(File.read(options[:auth_key]), options[:auth_key_password])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
http.open_timeout = options[:timeout] || 1
|
40
|
+
http.read_timeout = options[:timeout] || 1
|
41
|
+
LVS::JsonService::Logger.debug "Connecting"
|
42
|
+
http.start
|
43
|
+
http
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def self.create_key(host, port, options)
|
49
|
+
"#{host}:#{port}:#{options.to_s}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'lvs/json_service/logger'
|
3
|
+
require 'lvs/json_service/connection_manager'
|
3
4
|
|
4
5
|
module LVS
|
5
6
|
module JsonService
|
@@ -9,36 +10,30 @@ module LVS
|
|
9
10
|
base.extend ClassMethods
|
10
11
|
end
|
11
12
|
|
12
|
-
module ClassMethods
|
13
|
-
|
13
|
+
module ClassMethods
|
14
14
|
def http_request_with_timeout(service, args, options)
|
15
|
-
|
16
15
|
uri = URI.parse(service)
|
17
|
-
|
18
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
19
|
-
if options[:encrypted] || require_ssl?
|
20
|
-
http.use_ssl = true
|
21
|
-
# Self-signed certs give streams of "warning: peer certificate won't be verified in this SSL session"
|
22
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
23
|
-
LVS::JsonService::Logger.debug "Using SSL"
|
24
|
-
if options[:auth_cert]
|
25
|
-
LVS::JsonService::Logger.debug "Using Auth"
|
26
|
-
http.cert = OpenSSL::X509::Certificate.new(File.read(options[:auth_cert]))
|
27
|
-
http.key = OpenSSL::PKey::RSA.new(File.read(options[:auth_key]), options[:auth_key_password])
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
http.open_timeout = options[:timeout] || 1
|
32
|
-
http.read_timeout = options[:timeout] || 1
|
33
16
|
|
34
17
|
req = Net::HTTP::Post.new(uri.path)
|
35
18
|
req.form_data = { "object_request" => args.to_json }
|
36
19
|
|
20
|
+
options[:encrypted] ||= require_ssl?
|
37
21
|
retries = options[:retries] || 0
|
22
|
+
hard_retries = 1 # For persistent connection failures
|
38
23
|
|
39
24
|
begin
|
40
|
-
retries -= 1
|
41
|
-
|
25
|
+
retries -= 1
|
26
|
+
|
27
|
+
http = LVS::JsonService::ConnectionManager.get_connection(uri.host, uri.port, options)
|
28
|
+
response = http.request(req)
|
29
|
+
|
30
|
+
rescue Errno::EPIPE, EOFError, Errno::ECONNRESET
|
31
|
+
hard_retries -= 1
|
32
|
+
if hard_retries >= 0
|
33
|
+
sleep(1)
|
34
|
+
LVS::JsonService::ConnectionManager.reset_connection(uri.host, uri.port, options)
|
35
|
+
retry
|
36
|
+
end
|
42
37
|
|
43
38
|
rescue Timeout::Error => e
|
44
39
|
if retries >= 0
|
@@ -83,21 +78,27 @@ module LVS
|
|
83
78
|
response, result = Rails.cache.fetch([service, args].cache_key, :expires_in => options[:cached_for]) do
|
84
79
|
start = Time.now
|
85
80
|
response = http_request_with_timeout(service, args, options)
|
81
|
+
net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
82
|
+
start = Time.now
|
86
83
|
result = JSON.parse(response.body)
|
87
|
-
|
84
|
+
parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
85
|
+
timing = "Net: #{net_timing}, Parse: #{parse_timing}"
|
88
86
|
[response, result]
|
89
87
|
end
|
90
88
|
else
|
91
89
|
start = Time.now
|
92
90
|
response = http_request_with_timeout(service, args, options)
|
91
|
+
net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
92
|
+
start = Time.now
|
93
93
|
result = JSON.parse(response.body)
|
94
|
-
|
94
|
+
parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
95
|
+
timing = "Net: #{net_timing}, Parse: #{parse_timing}"
|
95
96
|
end
|
96
|
-
|
97
|
+
|
97
98
|
if response.body.size < 1024 || options[:debug]
|
98
99
|
LVS::JsonService::Logger.debug "Response (#{timing}): #{response.body.gsub(/\n/, '')}"
|
99
100
|
else
|
100
|
-
LVS::JsonService::Logger.debug "Response Snippet (#{timing}
|
101
|
+
LVS::JsonService::Logger.debug "Response Snippet (#{timing} / #{"%.1f" % (response.body.size/1024)}kB): #{response.body.gsub(/\n/, '')[0..1024]}"
|
101
102
|
end
|
102
103
|
if result.is_a?(Hash) && result.has_key?("PCode")
|
103
104
|
raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require File.dirname(__FILE__) + '/mock_net_http'
|
3
|
+
|
4
|
+
describe LVS::JsonService::ConnectionManager do
|
5
|
+
before :each do
|
6
|
+
LVS::JsonService::ConnectionManager.reset_all_connections
|
7
|
+
Net::HTTP.stub!(:new).and_return {MockNetHttp.new}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return a new HTTP object on the first call" do
|
11
|
+
http = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
12
|
+
http.class.should eql(MockNetHttp)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return an existing HTTP object on subsequent calls" do
|
16
|
+
http = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
17
|
+
http_subsequent = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
18
|
+
http.should eql(http_subsequent)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should reset the connection to a new object if requested" do
|
22
|
+
http = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
23
|
+
LVS::JsonService::ConnectionManager.reset_connection('www.google.com', 80, {})
|
24
|
+
http_subsequent = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
25
|
+
http.should_not eql(http_subsequent)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should reset all connections to requested" do
|
29
|
+
http_google = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
30
|
+
http_yahoo = LVS::JsonService::ConnectionManager.get_connection('www.yahoo.com', 80, {})
|
31
|
+
|
32
|
+
LVS::JsonService::ConnectionManager.reset_all_connections
|
33
|
+
|
34
|
+
http_google_subsequent = LVS::JsonService::ConnectionManager.get_connection('www.google.com', 80, {})
|
35
|
+
http_yahoo_subsequent = LVS::JsonService::ConnectionManager.get_connection('www.yahoo.com', 80, {})
|
36
|
+
|
37
|
+
http_google.should_not eql(http_google_subsequent)
|
38
|
+
http_yahoo.should_not eql(http_yahoo_subsequent)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
__END__
|
44
|
+
|
45
|
+
describe ".http_request_with_timeout" do
|
46
|
+
before :each do
|
47
|
+
@mock_post = mock(:post, :null_object => true)
|
48
|
+
Net::HTTP::Post.stub!(:new).and_return(@mock_post)
|
49
|
+
|
50
|
+
@mock_http = MockNetHttp.new
|
51
|
+
@connection = @mock_http.connection
|
52
|
+
Net::HTTP.stub!(:new).and_return(@mock_http)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should set Net::HTTP#open_timeout" do
|
56
|
+
@mock_http.should_receive(:open_timeout=).with(@options[:timeout])
|
57
|
+
do_request
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set Net::HTTP#read_timeout" do
|
61
|
+
@mock_http.should_receive(:read_timeout=).with(@options[:timeout])
|
62
|
+
do_request
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should default to a timeout of 1 if not set" do
|
66
|
+
@options = {:timeout => nil}
|
67
|
+
@mock_http.should_receive(:read_timeout=).with(1)
|
68
|
+
do_request
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should pass through the domain and port to Net::HTTP" do
|
72
|
+
Net::HTTP.should_receive(:new).with(@domain, @port).and_return(@mock_http)
|
73
|
+
do_request
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should create a Net::HTTP::Post object" do
|
77
|
+
Net::HTTP::Post.should_receive(:new).with(@path).and_return(@mock_post)
|
78
|
+
do_request
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should assign the JSON parameters to a Net::HTTP::Post object" do
|
82
|
+
@mock_post.should_receive(:form_data=).with({ "object_request" => @args.to_json })
|
83
|
+
do_request
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should send one request to Net::HTTP#start" do
|
87
|
+
@connection.should_receive(:request).once.with(@mock_post)
|
88
|
+
do_request
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return the response from the service" do
|
92
|
+
response = "some response"
|
93
|
+
@connection.should_receive(:request).and_return(response)
|
94
|
+
do_request.should == response
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "with 2 retries of Timeout::Error" do
|
98
|
+
|
99
|
+
before :each do
|
100
|
+
@options = {:retries => 2}
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "with subsequent success" do
|
104
|
+
|
105
|
+
it "should post the request 2 times" do
|
106
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_raise(Timeout::Error.new(nil))
|
107
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered
|
108
|
+
do_request
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return the response from the service" do
|
112
|
+
response = "some response"
|
113
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_raise(Timeout::Error.new(nil))
|
114
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_return(response)
|
115
|
+
do_request.should == response
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should log the retry attempt" do
|
121
|
+
@connection.stub!(:request).and_raise(Timeout::Error.new(nil))
|
122
|
+
LVS::JsonService::Logger.stub!(:debug)
|
123
|
+
LVS::JsonService::Logger.should_receive(:debug).at_least(1).times.
|
124
|
+
with("Retrying #{@url} due to TimeoutError")
|
125
|
+
do_request_catching_errors
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "with subseqent failure" do
|
129
|
+
|
130
|
+
before :each do
|
131
|
+
@connection.stub!(:request).and_raise(Timeout::Error.new(nil))
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should post the request 3 times (original + 2 retries)" do
|
135
|
+
@connection.should_receive(:request).with(@mock_post).exactly(3).times.and_raise(Timeout::Error.new(nil))
|
136
|
+
do_request_catching_errors
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should raise an LVS::JsonService::TimeoutError exception" do
|
140
|
+
lambda {
|
141
|
+
do_request
|
142
|
+
}.should raise_error(LVS::JsonService::TimeoutError)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "with 2 retries of Errno::ECONNREFUSED" do
|
149
|
+
|
150
|
+
before :each do
|
151
|
+
@options = {:retries => 2}
|
152
|
+
ClassWithRequest.stub!(:sleep)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should sleep for 1 second before each timeout" do
|
156
|
+
@connection.stub!(:request).and_raise(Errno::ECONNREFUSED)
|
157
|
+
ClassWithRequest.should_receive(:sleep).with(1)
|
158
|
+
do_request_catching_errors
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "with subsequent success" do
|
162
|
+
|
163
|
+
it "should post the request 2 times" do
|
164
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_raise(Errno::ECONNREFUSED)
|
165
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered
|
166
|
+
do_request
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should return the response from the service" do
|
170
|
+
response = "some response"
|
171
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_raise(Errno::ECONNREFUSED)
|
172
|
+
@connection.should_receive(:request).with(@mock_post).exactly(1).times.ordered.and_return(response)
|
173
|
+
do_request.should == response
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "with subsequent failure" do
|
178
|
+
|
179
|
+
before :each do
|
180
|
+
@connection.stub!(:request).and_raise(Errno::ECONNREFUSED)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should post the request 3 times (original + 2 retries)" do
|
184
|
+
@connection.should_receive(:request).with(@mock_post).exactly(3).times.and_raise(Errno::ECONNREFUSED)
|
185
|
+
do_request_catching_errors
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should raise an LVS::JsonService::BackendUnavailableError exception" do
|
189
|
+
lambda {
|
190
|
+
do_request
|
191
|
+
}.should raise_error(LVS::JsonService::BackendUnavailableError)
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should log the retry attempt" do
|
197
|
+
@connection.stub!(:request).and_raise(Errno::ECONNREFUSED)
|
198
|
+
LVS::JsonService::Logger.stub!(:debug)
|
199
|
+
LVS::JsonService::Logger.should_receive(:debug).at_least(1).times.
|
200
|
+
with("Retrying #{@url} due to Errno::ECONNREFUSED")
|
201
|
+
do_request_catching_errors
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should raise LVS::JsonService::NotFoundError if Net::HTTPNotFound is raised" do
|
206
|
+
@connection.stub!(:request).and_return(Net::HTTPNotFound.new(404, 1.1, "Not Found"))
|
207
|
+
lambda {
|
208
|
+
do_request
|
209
|
+
}.should raise_error(LVS::JsonService::NotFoundError)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should raise LVS::JsonService::NotModified if HTTPNotModified is raised" do
|
213
|
+
@connection.stub!(:request).and_return(Net::HTTPNotModified.new(304, 1.1, "Not Modified"))
|
214
|
+
lambda {
|
215
|
+
do_request
|
216
|
+
}.should raise_error(LVS::JsonService::NotModified)
|
217
|
+
end
|
218
|
+
|
219
|
+
def do_request
|
220
|
+
ClassWithRequest.http_request_with_timeout(@url, @args, @options)
|
221
|
+
end
|
222
|
+
|
223
|
+
def do_request_catching_errors
|
224
|
+
do_request
|
225
|
+
rescue LVS::JsonService::Error
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
describe ".run_remote_request" do
|
231
|
+
before :each do
|
232
|
+
@response = load_fixture('response.yml')
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should call http_request_with_timeout with service, args and options" do
|
236
|
+
ClassWithRequest.should_receive(:http_request_with_timeout).
|
237
|
+
with(@url, @args, @options).
|
238
|
+
and_return(@response)
|
239
|
+
ClassWithRequest.run_remote_request(@url, @args, @options)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should return the parsed JSON result" do
|
243
|
+
expected_result = [
|
244
|
+
{"id"=>1100, "description"=>"Handball (ABP)"},
|
245
|
+
{"id"=>978400, "description"=>"Casino Roulette"}
|
246
|
+
]
|
247
|
+
ClassWithRequest.stub!(:http_request_with_timeout).and_return(@response)
|
248
|
+
ClassWithRequest.run_remote_request(@url, @args, @options).should == expected_result
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should raise an error if the response contains PCode" do
|
252
|
+
error_response = load_fixture('error_response.yml')
|
253
|
+
ClassWithRequest.stub!(:http_request_with_timeout).
|
254
|
+
and_return(error_response)
|
255
|
+
|
256
|
+
lambda {
|
257
|
+
ClassWithRequest.run_remote_request(@url, @args, @options)
|
258
|
+
}.should raise_error(LVS::JsonService::Error)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
def load_fixture (file)
|
265
|
+
response_file = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', file)
|
266
|
+
YAML.load_file(response_file)
|
267
|
+
end
|
268
|
+
|
269
|
+
class MockNetHttp
|
270
|
+
|
271
|
+
attr_accessor :connection
|
272
|
+
|
273
|
+
def initialize(*args)
|
274
|
+
@connection = mock(:connection)
|
275
|
+
end
|
276
|
+
|
277
|
+
def start
|
278
|
+
yield @connection if block_given?
|
279
|
+
end
|
280
|
+
|
281
|
+
def method_missing(*args)
|
282
|
+
return self
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
class ClassWithRequest
|
288
|
+
include LVS::JsonService::Request
|
289
|
+
|
290
|
+
def self.require_ssl?
|
291
|
+
false
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
class TestServiceForJsonMethodsCall < LVS::JsonService::Base
|
4
|
+
self.agp_location = "http://doesntmatter.anything"
|
5
|
+
self.site = 'testjsonservices/'
|
6
|
+
self.service_prefix = 'com.json.commands.'
|
7
|
+
self.field_prefix = 'event_'
|
8
|
+
|
9
|
+
fake_service :details,
|
10
|
+
'{"id":1, "status":"OK", "count":2, "startDate":1240498565709, "hasOwner":1,
|
11
|
+
"bets":[{"betAmount":123}, {"betAmount":456}],
|
12
|
+
"startDate":1240498565709, "with123":1}'
|
13
|
+
end
|
14
|
+
|
15
|
+
describe LVS::JsonService::Base do
|
16
|
+
it "should include an array of bets" do
|
17
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).bets.should be_an(Array)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should respond to bet_amount on the first element of the array of bets" do
|
21
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).bets[0].respond_to?(:bet_amount).should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not respond to bet_other on the first element of the array of bets" do
|
25
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).bets[0].respond_to?(:bet_other).should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have an id of 1" do
|
29
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).id.should eql(1)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a first child in the bets array with a bet_amount parameter of 123" do
|
33
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).bets.first.bet_amount.should eql(123)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a working question mark method for boolean field has_owner" do
|
37
|
+
TestServiceForJsonMethodsCall.details(:num_results => 5).owner?.should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should convert date columns to dates" do
|
41
|
+
TestServiceForJsonMethodsCall.details.start_date.utc.to_s(:rfc822).should eql("Thu, 23 Apr 2009 14:56:05 +0000")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should recognise keys with integers in them" do
|
45
|
+
TestServiceForJsonMethodsCall.details.with123.should eql(1)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should find camelCase attributes using camelCase or ruby_sytax" do
|
49
|
+
class AttributeNames < LVS::JsonService::Base
|
50
|
+
self.ignore_missing = true
|
51
|
+
fake_service :call, '{"longMethodName":1}'
|
52
|
+
end
|
53
|
+
obj = AttributeNames.call
|
54
|
+
obj.longMethodName.should eql(1)
|
55
|
+
obj.long_method_name.should eql(1)
|
56
|
+
end
|
57
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require File.dirname(__FILE__) + '/mock_net_http'
|
2
3
|
|
3
4
|
# Explicitly requiring this now to ensure it is loaded before we try to
|
4
5
|
# unmarshall response from the yaml fixture file.
|
@@ -13,6 +14,7 @@ describe LVS::JsonService::Request do
|
|
13
14
|
|
14
15
|
@args = {:some => "thing"}
|
15
16
|
@options= {:timeout => 100}
|
17
|
+
LVS::JsonService::ConnectionManager.reset_all_connections
|
16
18
|
end
|
17
19
|
|
18
20
|
describe ".http_request_with_timeout" do
|
@@ -92,6 +94,7 @@ describe LVS::JsonService::Request do
|
|
92
94
|
|
93
95
|
it "should log the retry attempt" do
|
94
96
|
@connection.stub!(:request).and_raise(Timeout::Error.new(nil))
|
97
|
+
LVS::JsonService::Logger.stub!(:debug)
|
95
98
|
LVS::JsonService::Logger.should_receive(:debug).at_least(1).times.
|
96
99
|
with("Retrying #{@url} due to TimeoutError")
|
97
100
|
do_request_catching_errors
|
@@ -167,6 +170,7 @@ describe LVS::JsonService::Request do
|
|
167
170
|
|
168
171
|
it "should log the retry attempt" do
|
169
172
|
@connection.stub!(:request).and_raise(Errno::ECONNREFUSED)
|
173
|
+
LVS::JsonService::Logger.stub!(:debug)
|
170
174
|
LVS::JsonService::Logger.should_receive(:debug).at_least(1).times.
|
171
175
|
with("Retrying #{@url} due to Errno::ECONNREFUSED")
|
172
176
|
do_request_catching_errors
|
@@ -237,24 +241,6 @@ def load_fixture (file)
|
|
237
241
|
YAML.load_file(response_file)
|
238
242
|
end
|
239
243
|
|
240
|
-
class MockNetHttp
|
241
|
-
|
242
|
-
attr_accessor :connection
|
243
|
-
|
244
|
-
def initialize(*args)
|
245
|
-
@connection = mock(:connection)
|
246
|
-
end
|
247
|
-
|
248
|
-
def start
|
249
|
-
yield @connection
|
250
|
-
end
|
251
|
-
|
252
|
-
def method_missing(*args)
|
253
|
-
return self
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
244
|
class ClassWithRequest
|
259
245
|
include LVS::JsonService::Request
|
260
246
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
class TestServiceForFakingCall < LVS::JsonService::Base
|
4
|
+
self.agp_location = "http://doesntmatter.anything"
|
5
|
+
self.site = 'testjsonservices/'
|
6
|
+
self.service_prefix = 'com.json.commands.'
|
7
|
+
self.field_prefix = 'event_'
|
8
|
+
|
9
|
+
fake_service :details,
|
10
|
+
'{"id":1, "status":"OK", "count":2, "startDate":1240498565709, "hasOwner":1,
|
11
|
+
"bets":[{"betAmount":123}, {"betAmount":456}],
|
12
|
+
"startDate":1240498565709}'
|
13
|
+
end
|
14
|
+
|
15
|
+
describe LVS::JsonService::Base do
|
16
|
+
it "should return stored values as is without playing" do
|
17
|
+
|
18
|
+
obj = TestServiceForFakingCall.details
|
19
|
+
test_hash = {:abc => [1, 2, 3]}
|
20
|
+
obj.status = test_hash
|
21
|
+
obj.status.should eql(test_hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: LVS-JSONService
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LVS
|
8
|
+
- andyjeffries
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
@@ -34,16 +35,22 @@ files:
|
|
34
35
|
- lib/lvs/json_service/base.rb
|
35
36
|
- lib/lvs/json_service/logger.rb
|
36
37
|
- lib/lvs/json_service/request.rb
|
38
|
+
- lib/lvs/json_service/connection_manager.rb
|
37
39
|
- spec/fixtures/error_response.yml
|
38
40
|
- spec/fixtures/response.yml
|
39
41
|
- spec/json_service_spec.rb
|
40
42
|
- spec/lvs/json_service/base_spec.rb
|
43
|
+
- spec/lvs/json_service/connection_manager_spec.rb
|
44
|
+
- spec/lvs/json_service/json_methods_spec.rb
|
41
45
|
- spec/lvs/json_service/logger_spec.rb
|
42
46
|
- spec/lvs/json_service/request_spec.rb
|
47
|
+
- spec/lvs/json_service/mock_net_http.rb
|
48
|
+
- spec/lvs/json_service/setting_fields_spec.rb
|
43
49
|
- spec/spec.opts
|
44
50
|
- spec/spec_helper.rb
|
45
51
|
has_rdoc: false
|
46
52
|
homepage: http://github.com/lvs/JSONService
|
53
|
+
licenses:
|
47
54
|
post_install_message:
|
48
55
|
rdoc_options:
|
49
56
|
- --charset=UTF-8
|
@@ -64,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
71
|
requirements: []
|
65
72
|
|
66
73
|
rubyforge_project:
|
67
|
-
rubygems_version: 1.
|
74
|
+
rubygems_version: 1.3.5
|
68
75
|
signing_key:
|
69
76
|
specification_version: 3
|
70
77
|
summary: A Ruby library for interacting with external JSON services
|