jsonrpc2 0.1.0 → 0.1.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fb244988f3e6da4bd9e07cb696ae0527dc60c5ec
4
+ data.tar.gz: 8b378af79f04b2603d6ac7ad669918bb9e055962
5
+ SHA512:
6
+ metadata.gz: 8ec025d776da30ad4251511f1907cad21fe1dc76580a907113417fe7e658de63435ec67976b96488c02b41806ab794452e1aad695769cb60059fc9d6dc35ceb7
7
+ data.tar.gz: 0f7017e7d77711638377d340d7aae1a6355ddca9b40a0ec7e0218c16dd31bc33a364a7e07acdcf10b9a991c1465987bda927fae0c0cb90c245028ebeb38fc8f3
@@ -4,6 +4,9 @@ A Rack compatible, documenting JSON-RPC 2 DSL/server implementation for ruby.
4
4
 
5
5
  ## Changes
6
6
 
7
+ * 0.1.1 - 4-Jan-2013
8
+ Improve logging of exceptions / failure
9
+
7
10
  * 0.1.0 - 4-Jan-2013
8
11
  Turn on timing & logging of all requests
9
12
 
@@ -13,6 +13,7 @@ class ::Object::Calculator < JSONRPC2::Interface
13
13
  param 'b', 'Number', 'b'
14
14
  result 'Number', 'a * b'
15
15
  def mul
16
+ raise JSONRPC2::KnownError, [123, "Don't like negative numbers", params] if params['a'] < 0 or params['b'] < 0
16
17
  params['a'] * params['b']
17
18
  end
18
19
 
@@ -61,6 +61,7 @@ class Interface
61
61
  # @param [Hash] environment Rack environment hash
62
62
  # @return [Array<Fixnum, Hash<String,String>, Array<String>>] Rack-compatible response
63
63
  def call(environment)
64
+ environment['json.request-id'] = Digest::MD5.hexdigest("#{$host ||= Socket.gethostname}-#{$$}-#{Time.now.to_f}")[0,8]
64
65
  request = Rack::Request.new(environment)
65
66
  catch :rack_response do
66
67
  best = JSONRPC2::HTTPUtils.which(environment['HTTP_ACCEPT'], %w[text/html application/json-rpc application/json])
@@ -84,8 +85,8 @@ class Interface
84
85
  end
85
86
 
86
87
  rescue Exception => e
87
- if env['rack.logger'].respond_to?(:error)
88
- env['rack.logger'].error "#{e.class}: #{e.message} - #{e.backtrace * "\n "}"
88
+ if environment['rack.logger'].respond_to?(:error)
89
+ environment['rack.logger'].error "#{e.class}: #{e.message} - #{e.backtrace * "\n "}"
89
90
  end
90
91
  raise e.class, e.message, e.backtrace
91
92
  end
@@ -99,13 +100,13 @@ class Interface
99
100
  else
100
101
  auth = env["HTTP_AUTHORIZATION"]
101
102
  end
102
- env['rack.logger'].info("[#{Time.now.strftime('%d/%m/%Y %H:%M:%S')}] [JSON-RPC2] #{env['REQUEST_URI']} - Auth: #{auth}, Data: #{data.inspect}")
103
+ env['rack.logger'].info("[JSON-RPC2] #{env['json.request-id']} #{env['REQUEST_URI']} - Auth: #{auth}, Data: #{data.is_a?(String) ? data : data.inspect}")
103
104
  end
104
105
  t = Time.now.to_f
105
106
  return yield
106
107
  ensure
107
108
  if env['rack.logger'].respond_to?(:info)
108
- env['rack.logger'].info("[#{Time.now.strftime('%d/%m/%Y %H:%M:%S')}] [JSON-RPC2] Completed in #{'%.3f' % ((Time.now.to_f - t) * 1000)}ms")
109
+ env['rack.logger'].info("[JSON-RPC2] #{env['json.request-id']} Completed in #{'%.3f' % ((Time.now.to_f - t) * 1000)}ms#{ $! ? " - exception = #{$!.class}:#{$!.message}" : "" }")
109
110
  end
110
111
  end
111
112
 
@@ -133,12 +134,14 @@ class Interface
133
134
  # @param [Hash,Array] rpc_data Array of calls or Hash containing one call
134
135
  # @return [Hash,Array] Depends on input, but either a hash result or an array of results corresponding to calls.
135
136
  def dispatch(rpc_data)
136
- case rpc_data
137
+ result = case rpc_data
137
138
  when Array
138
- rpc_data.map { |rpc| dispatch_single(rpc) }.to_json
139
+ rpc_data.map { |rpc| dispatch_single(rpc) }
139
140
  else
140
- dispatch_single(rpc_data).to_json
141
+ dispatch_single(rpc_data)
141
142
  end
143
+
144
+ return result.to_json
142
145
  end
143
146
 
144
147
  protected
@@ -162,17 +165,32 @@ class Interface
162
165
  def request
163
166
  @_jsonrpc_request
164
167
  end
168
+ def env
169
+ @_jsonrpc_env
170
+ end
165
171
 
166
172
  # Logger
167
173
  def logger
168
- @_jsonrpc_logger ||= (request['rack.logger'] || Rack::NullLogger.new("null"))
174
+ @_jsonrpc_logger ||= (@_jsonrpc_env['rack.logger'] || Rack::NullLogger.new("null"))
169
175
  end
170
176
  # Check call validity and authentication & make a single method call
171
177
  #
172
178
  # @param [Hash] rpc JSON-RPC-2 call
173
179
  def dispatch_single(rpc)
174
180
  t = Time.now.to_f
175
- logger.info("[JSON-RPC2] Call #{rpc.inspect}\n")
181
+
182
+ result = _dispatch_single(rpc)
183
+
184
+ if result['result']
185
+ logger.info("[JSON-RPC2] #{env['json.request-id']} Call completed OK in #{'%.3f' % ((Time.now.to_f - t) * 1000)}ms")
186
+ elsif result['error']
187
+ logger.info("[JSON-RPC2] #{env['json.request-id']} Call to ##{rpc['method']} failed in #{'%.3f' % ((Time.now.to_f - t) * 1000)}ms with error #{result['error']['code']} - #{result['error']['message']}")
188
+ end
189
+
190
+ result
191
+ end
192
+ def _dispatch_single(rpc)
193
+ t = Time.now.to_f
176
194
  unless rpc.has_key?('id') && rpc.has_key?('method') && rpc['jsonrpc'].eql?('2.0')
177
195
  return response_error(-32600, 'Invalid request', nil)
178
196
  end
@@ -191,10 +209,10 @@ class Interface
191
209
  rescue KnownError => e
192
210
  response_error(e.code, e.message, e.data) # XXX: Change me
193
211
  rescue Exception => e
212
+ logger.error("#{env['json.request-id']} Internal error calling #{rpc.inspect} - #{e.class}: #{e.message} #{e.backtrace.join("\n ")}") if logger.respond_to?(:error)
194
213
  response_error(-32000, "#{e.class}: #{e.message}", e.backtrace) # XXX: Change me
214
+ else
195
215
  end
196
- ensure
197
- logger.info("[JSON-RPC2] Call completed in #{'%.3f' % ((Time.now.to_f - t) * 1000)}ms\n")
198
216
  end
199
217
  # List API methods
200
218
  #
@@ -1,5 +1,5 @@
1
1
  # JSONRPC2 namespace module
2
2
  module JSONRPC2
3
3
  # Version
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
metadata CHANGED
@@ -1,124 +1,92 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: jsonrpc2
3
- version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 0
10
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Geoff Youngs
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2014-01-04 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: httpclient
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
32
20
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: json
36
21
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
46
34
  type: :runtime
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: RedCloth
50
35
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: RedCloth
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
60
48
  type: :runtime
61
- version_requirements: *id003
62
- - !ruby/object:Gem::Dependency
63
- name: thor
64
49
  prerelease: false
65
- requirement: &id004 !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
74
62
  type: :runtime
75
- version_requirements: *id004
76
- description: |+
77
- == Description
78
-
79
- A Rack compatible JSON-RPC2 server domain specific language (DSL) - allows JSONRPC APIs to be
80
- defined as mountable Rack applications with inline documentation, authentication and type checking.
81
-
82
- e.g.
83
-
84
- class Calculator < JSONRPC2::Interface
85
- title "JSON-RPC2 Calculator"
86
- introduction "This interface allows basic maths calculations via JSON-RPC2"
87
- auth_with JSONRPC2::BasicAuth.new({'user' => 'secretword'})
88
-
89
- section 'Simple Ops' do
90
- desc 'Multiply two numbers'
91
- param 'a', 'Number', 'a'
92
- param 'b', 'Number', 'b'
93
- result 'Number', 'a * b'
94
- def mul args
95
- args['a'] * args['b']
96
- end
97
-
98
- desc 'Add numbers'
99
- example "Calculate 1 + 1 = 2", :params => { 'a' => 1, 'b' => 1}, :result => 2
100
-
101
- param 'a', 'Number', 'First number'
102
- param 'b', 'Number', 'Second number'
103
- optional 'c', 'Number', 'Third number'
104
- result 'Number', 'a + b + c'
105
- def sum args
106
- val = args['a'] + args['b']
107
- val += args['c'] if args['c']
108
- val
109
- end
110
- end
111
- end
112
-
113
- email:
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: "== Description\n\nA Rack compatible JSON-RPC2 server domain specific
70
+ language (DSL) - allows JSONRPC APIs to be \ndefined as mountable Rack applications
71
+ with inline documentation, authentication and type checking.\n\ne.g.\n\n class
72
+ Calculator < JSONRPC2::Interface\n title \"JSON-RPC2 Calculator\"\n introduction
73
+ \"This interface allows basic maths calculations via JSON-RPC2\"\n auth_with
74
+ JSONRPC2::BasicAuth.new({'user' => 'secretword'})\n\n section 'Simple Ops' do\n
75
+ \ desc 'Multiply two numbers'\n param 'a', 'Number', 'a'\n param
76
+ 'b', 'Number', 'b'\n result 'Number', 'a * b'\n def mul args\n args['a']
77
+ * args['b']\n end\n\n desc 'Add numbers'\n example \"Calculate
78
+ 1 + 1 = 2\", :params => { 'a' => 1, 'b' => 1}, :result => 2\n\n param 'a',
79
+ 'Number', 'First number'\n param 'b', 'Number', 'Second number'\n optional
80
+ 'c', 'Number', 'Third number'\n result 'Number', 'a + b + c'\n def
81
+ sum args\n val = args['a'] + args['b']\n val += args['c'] if args['c']\n
82
+ \ val\n end\n end\n end\n\n"
83
+ email:
114
84
  - git@intersect-uk.co.uk
115
- executables:
85
+ executables:
116
86
  - jsonrpc2
117
87
  extensions: []
118
-
119
88
  extra_rdoc_files: []
120
-
121
- files:
89
+ files:
122
90
  - .gitignore
123
91
  - Gemfile
124
92
  - README.markdown
@@ -145,37 +113,25 @@ files:
145
113
  - test/test_types.rb
146
114
  homepage: http://github.com/geoffyoungs/jsonrpc2
147
115
  licenses: []
148
-
116
+ metadata: {}
149
117
  post_install_message:
150
118
  rdoc_options: []
151
-
152
- require_paths:
119
+ require_paths:
153
120
  - lib
154
- required_ruby_version: !ruby/object:Gem::Requirement
155
- none: false
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- hash: 3
160
- segments:
161
- - 0
162
- version: "0"
163
- required_rubygems_version: !ruby/object:Gem::Requirement
164
- none: false
165
- requirements:
166
- - - ">="
167
- - !ruby/object:Gem::Version
168
- hash: 3
169
- segments:
170
- - 0
171
- version: "0"
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
172
131
  requirements: []
173
-
174
132
  rubyforge_project:
175
- rubygems_version: 1.8.15
133
+ rubygems_version: 2.0.3
176
134
  signing_key:
177
- specification_version: 3
135
+ specification_version: 4
178
136
  summary: JSON-RPC2 server DSL
179
137
  test_files: []
180
-
181
- has_rdoc: