LVS-JSONService 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.specification +1 -1
- data/LVS-JSONService.gemspec +2 -2
- data/VERSION +1 -1
- data/lib/json_service.rb +4 -0
- data/lib/lvs/json_service/base.rb +41 -21
- data/lib/lvs/json_service/request.rb +88 -33
- metadata +2 -2
data/.specification
CHANGED
data/LVS-JSONService.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{LVS-JSONService}
|
5
|
-
s.version = "0.4.
|
5
|
+
s.version = "0.4.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["LVS", "andyjeffries"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2010-01-19}
|
10
10
|
s.email = %q{info@lvs.co.uk}
|
11
11
|
s.extra_rdoc_files = [
|
12
12
|
"LICENSE",
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
data/lib/json_service.rb
CHANGED
@@ -12,15 +12,16 @@ module LVS
|
|
12
12
|
protected
|
13
13
|
|
14
14
|
class << self
|
15
|
-
@site
|
16
|
-
@services
|
17
|
-
@service_prefix
|
18
|
-
@field_prefix
|
19
|
-
@encrypted
|
20
|
-
@ignore_missing
|
21
|
-
@auth_cert
|
22
|
-
@auth_key
|
23
|
-
@auth_key_pass
|
15
|
+
@site = ""
|
16
|
+
@services = []
|
17
|
+
@service_prefix = ""
|
18
|
+
@field_prefix = ""
|
19
|
+
@encrypted = false
|
20
|
+
@ignore_missing = false
|
21
|
+
@auth_cert = ""
|
22
|
+
@auth_key = ""
|
23
|
+
@auth_key_pass = ""
|
24
|
+
@eventmachine_async = false
|
24
25
|
|
25
26
|
def encrypted=(value)
|
26
27
|
@encrypted = value
|
@@ -55,6 +56,10 @@ module LVS
|
|
55
56
|
@field_prefix = value
|
56
57
|
end
|
57
58
|
|
59
|
+
def is_eventmachine_async!
|
60
|
+
@eventmachine_async = true
|
61
|
+
end
|
62
|
+
|
58
63
|
def site=(value)
|
59
64
|
# value is containing AGP_LOCATION already sometimes:
|
60
65
|
value.gsub!(/^#{AGP_LOCATION}/, '') if defined?(AGP_LOCATION) && value.match(/#{AGP_LOCATION}/)
|
@@ -80,7 +85,7 @@ module LVS
|
|
80
85
|
(Module.const_defined?(:SSL_ENABLED) && SSL_ENABLED) || (Module.const_defined?(:SSL_DISABLED) && !SSL_DISABLED)
|
81
86
|
end
|
82
87
|
|
83
|
-
def define_service(name, service, options = {})
|
88
|
+
def define_service(name, service, options = {}, &block)
|
84
89
|
service_name = name
|
85
90
|
|
86
91
|
service_path = service.split('.')
|
@@ -92,12 +97,13 @@ module LVS
|
|
92
97
|
prefix = service_path[0..-3].join('.') + '.'
|
93
98
|
end
|
94
99
|
|
95
|
-
options[:encrypted]
|
96
|
-
options[:
|
97
|
-
options[:
|
98
|
-
options[:
|
100
|
+
options[:encrypted] = @encrypted if @encrypted
|
101
|
+
options[:eventmachine_async] = @eventmachine_async if @eventmachine_async
|
102
|
+
options[:auth_cert] = @auth_cert if @auth_cert
|
103
|
+
options[:auth_key] = @auth_key if @auth_key
|
104
|
+
options[:auth_key_pass] = @auth_key_pass if @auth_key_pass
|
99
105
|
|
100
|
-
(class<<self;self;end).send :define_method, service_name do |*args|
|
106
|
+
(class<<self;self;end).send :define_method, service_name do |*args, &block|
|
101
107
|
method_params, flags = args
|
102
108
|
|
103
109
|
method_params ||= {}
|
@@ -109,11 +115,22 @@ module LVS
|
|
109
115
|
options[:required].each do |key|
|
110
116
|
raise LVS::JsonService::Error.new("Required field #{key} wasn't supplied", internal_service, '0', method_params) if method_params[key].blank?
|
111
117
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
118
|
+
if block
|
119
|
+
self.run_remote_request(@site + prefix + internal_service, method_params, options) do |result|
|
120
|
+
if flags && flags[:raw]
|
121
|
+
yield(result)
|
122
|
+
else
|
123
|
+
block.call(self.parse_result(result))
|
124
|
+
end
|
125
|
+
end
|
115
126
|
else
|
116
|
-
self.
|
127
|
+
result = self.run_remote_request(@site + prefix + internal_service, method_params, options)
|
128
|
+
puts "In service call non-block"
|
129
|
+
if flags && flags[:raw]
|
130
|
+
result
|
131
|
+
else
|
132
|
+
self.parse_result(result)
|
133
|
+
end
|
117
134
|
end
|
118
135
|
end
|
119
136
|
|
@@ -132,7 +149,9 @@ module LVS
|
|
132
149
|
end
|
133
150
|
|
134
151
|
def parse_result(response)
|
135
|
-
if response.is_a?(
|
152
|
+
if response.is_a?(LVS::JsonService::Error)
|
153
|
+
response
|
154
|
+
elsif response.is_a?(Array)
|
136
155
|
array = response.map { |x| self.new(x) }
|
137
156
|
else
|
138
157
|
self.new(response)
|
@@ -267,7 +286,7 @@ module LVS
|
|
267
286
|
end
|
268
287
|
|
269
288
|
class Error < StandardError
|
270
|
-
attr_reader :message, :code, :service, :args, :json_response
|
289
|
+
attr_reader :message, :code, :service, :args, :json_response, :backtrace
|
271
290
|
|
272
291
|
def initialize(message, code=nil, service=nil, args=nil, response=nil)
|
273
292
|
@message = message
|
@@ -275,6 +294,7 @@ module LVS
|
|
275
294
|
@service = service
|
276
295
|
@args = args
|
277
296
|
@json_response = response
|
297
|
+
@backtrace = caller
|
278
298
|
|
279
299
|
super "#{message}\n#{service} (#{args.inspect})"
|
280
300
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'ostruct'
|
2
3
|
require 'lvs/json_service/logger'
|
3
4
|
require 'lvs/json_service/connection_manager'
|
4
5
|
|
@@ -15,7 +16,7 @@ module LVS
|
|
15
16
|
Digest::SHA1.hexdigest((rand(4294967295)+Time.now.usec).to_s)
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
+
def http_standard_request_with_timeout(service, args, options)
|
19
20
|
uri = URI.parse(service)
|
20
21
|
|
21
22
|
req = Net::HTTP::Post.new(uri.path)
|
@@ -65,7 +66,6 @@ module LVS
|
|
65
66
|
|
66
67
|
rescue OpenSSL::SSL::SSLError => e
|
67
68
|
raise LVS::JsonService::BackendUnavailableError.new("Backend unavailable #{e}", 500, service, args)
|
68
|
-
|
69
69
|
end
|
70
70
|
|
71
71
|
if response.is_a?(Net::HTTPNotFound)
|
@@ -76,55 +76,110 @@ module LVS
|
|
76
76
|
raise LVS::JsonService::NotModified.new("304 Data hasn't changed", 304, service, args)
|
77
77
|
end
|
78
78
|
|
79
|
-
response
|
79
|
+
yield(response)
|
80
|
+
end
|
81
|
+
|
82
|
+
def http_eventmachine_request_with_timeout(service, args, options)
|
83
|
+
http_options = {}
|
84
|
+
http_options[:timeout] = options[:timeout] || 1
|
85
|
+
http_options[:head] = {"X-LVS-Request-ID" => options[:request_id]}
|
86
|
+
http_options[:body] = {"object_request" => args.to_json}
|
87
|
+
|
88
|
+
http = EventMachine::HttpRequest.new(service).post(http_options)
|
89
|
+
http.callback {
|
90
|
+
response = OpenStruct.new(:request_id => http.response_header["X-LVS-Request-ID"], :body => http.response)
|
91
|
+
yield(response)
|
92
|
+
}
|
93
|
+
http.errback {
|
94
|
+
if (http.response_header.status == 404)
|
95
|
+
yield(LVS::JsonService::NotFoundError.new("404 Found for the service #{service}", 404, service, args))
|
96
|
+
elsif (http.response_header.status == 304)
|
97
|
+
yield(LVS::JsonService::NotModified.new("304 Data hasn't changed", 304, service, args))
|
98
|
+
elsif (http.response_header.status == 0)
|
99
|
+
yield(LVS::JsonService::BackendUnavailableError.new("Backend unavailable (in time)", 500, service, args))
|
100
|
+
else
|
101
|
+
yield(LVS::JsonService::Error.new("Unknown error (#{http.response_header.inspect})", 500, service, args))
|
102
|
+
end
|
103
|
+
}
|
80
104
|
end
|
81
105
|
|
82
106
|
def run_remote_request(service, args, options = {})
|
83
107
|
LVS::JsonService::Logger.debug "Requesting '#{service}' with #{args.to_json}"
|
84
108
|
|
109
|
+
response = nil
|
110
|
+
result = nil
|
85
111
|
options[:request_id] = unique_request_id
|
112
|
+
|
86
113
|
if options[:cached_for]
|
87
114
|
timing = "CACHED"
|
88
|
-
response, result = Rails.cache.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
115
|
+
response, result = Rails.cache.read([service, args].cache_key, :expires_in => options[:cached_for])
|
116
|
+
end
|
117
|
+
if response.nil?
|
118
|
+
start = Time.now
|
119
|
+
if options[:eventmachine_async]
|
120
|
+
http_eventmachine_request_with_timeout(service, args, options) do |response|
|
121
|
+
if response.is_a?(LVS::JsonService::Error)
|
122
|
+
result = response
|
123
|
+
else
|
124
|
+
verify_request_id(response.request_id, options[:request_id])
|
125
|
+
net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
126
|
+
start = Time.now
|
127
|
+
result = JSON.parse(response.body)
|
128
|
+
parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
129
|
+
timing = "Net: #{net_timing}, Parse: #{parse_timing}"
|
130
|
+
if options[:cached_for]
|
131
|
+
Rails.cache.write([service, args].cache_key, [response, result], :expires_in => options[:cached_for])
|
132
|
+
end
|
133
|
+
log_response(timing, response.body, options)
|
134
|
+
if result.is_a?(Hash) && result.has_key?("PCode")
|
135
|
+
result = LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
yield(result) if block_given?
|
139
|
+
return result
|
140
|
+
end
|
141
|
+
else
|
142
|
+
http_standard_request_with_timeout(service, args, options) do |response|
|
143
|
+
verify_request_id(response["X-LVS-Request-ID"], options[:request_id])
|
144
|
+
net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
145
|
+
start = Time.now
|
146
|
+
result = JSON.parse(response.body)
|
147
|
+
parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
148
|
+
timing = "Net: #{net_timing}, Parse: #{parse_timing}"
|
149
|
+
if options[:cached_for]
|
150
|
+
Rails.cache.write([service, args].cache_key, [response, result], :expires_in => options[:cached_for])
|
151
|
+
end
|
152
|
+
log_response(timing, response.body, options)
|
153
|
+
if result.is_a?(Hash) && result.has_key?("PCode")
|
154
|
+
raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
|
155
|
+
end
|
156
|
+
yield(result) if block_given?
|
157
|
+
return result
|
158
|
+
end
|
98
159
|
end
|
99
160
|
else
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
start = Time.now
|
105
|
-
result = JSON.parse(response.body)
|
106
|
-
parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
|
107
|
-
timing = "Net: #{net_timing}, Parse: #{parse_timing}"
|
161
|
+
log_response(timing, response.body, options)
|
162
|
+
if result.is_a?(Hash) && result.has_key?("PCode")
|
163
|
+
raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
|
164
|
+
end
|
108
165
|
end
|
166
|
+
result
|
167
|
+
end
|
109
168
|
|
110
|
-
|
111
|
-
|
169
|
+
def log_response(timing, body, options)
|
170
|
+
if body.size < 1024 || options[:debug]
|
171
|
+
LVS::JsonService::Logger.debug "Response (#{timing}): #{body.gsub(/\n/, '')}"
|
112
172
|
else
|
113
|
-
LVS::JsonService::Logger.debug "Response Snippet (#{timing} / #{"%.1f" % (
|
114
|
-
end
|
115
|
-
if result.is_a?(Hash) && result.has_key?("PCode")
|
116
|
-
raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
|
173
|
+
LVS::JsonService::Logger.debug "Response Snippet (#{timing} / #{"%.1f" % (body.size/1024)}kB): #{body.gsub(/\n/, '')[0..1024]}"
|
117
174
|
end
|
118
|
-
result
|
119
175
|
end
|
120
176
|
|
121
|
-
def verify_request_id(
|
122
|
-
returned_request_id
|
123
|
-
|
124
|
-
raise LVS::JsonService::RequestMismatchError.new("The sent Request ID (#{request_id}) didn't " +
|
177
|
+
def verify_request_id(returned_request_id, sent_request_id)
|
178
|
+
if returned_request_id != sent_request_id && !returned_request_id.blank?
|
179
|
+
raise LVS::JsonService::RequestMismatchError.new("The sent Request ID (#{sent_request_id}) didn't " +
|
125
180
|
"match the returned Request ID (#{returned_request_id}) ")
|
126
181
|
else
|
127
|
-
LVS::JsonService::Logger.debug "Sent and received Request ID - #{
|
182
|
+
LVS::JsonService::Logger.debug "Sent and received Request ID - #{sent_request_id}"
|
128
183
|
end
|
129
184
|
end
|
130
185
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: LVS-JSONService
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LVS
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2010-01-19 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|