LVS-JSONService 0.3.0 → 0.3.2
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.
- 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
|