saorin 0.2.0 → 0.3.0
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/lib/saorin.rb +0 -1
- data/lib/saorin/client.rb +6 -3
- data/lib/saorin/client/base.rb +92 -0
- data/lib/saorin/client/faraday.rb +32 -0
- data/lib/saorin/registerable.rb +31 -0
- data/lib/saorin/server.rb +6 -4
- data/lib/saorin/server/base.rb +86 -0
- data/lib/saorin/server/rack.rb +33 -0
- data/lib/saorin/version.rb +1 -1
- data/saorin.gemspec +0 -1
- data/spec/{adapter → server}/base_spec.rb +6 -3
- data/spec/{adapter/servers → server}/rack_spec.rb +2 -2
- metadata +13 -36
- data/lib/saorin/adapters.rb +0 -2
- data/lib/saorin/adapters/clients.rb +0 -10
- data/lib/saorin/adapters/clients/base.rb +0 -94
- data/lib/saorin/adapters/clients/faraday.rb +0 -32
- data/lib/saorin/adapters/registerable.rb +0 -33
- data/lib/saorin/adapters/servers.rb +0 -10
- data/lib/saorin/adapters/servers/base.rb +0 -88
- data/lib/saorin/adapters/servers/rack.rb +0 -33
- data/lib/saorin/adapters/servers/reel.rb +0 -37
- data/server.rb +0 -13
- data/spec/adapter/servers/reel_spec.rb +0 -11
data/lib/saorin.rb
CHANGED
data/lib/saorin/client.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
require 'saorin/
|
1
|
+
require 'saorin/registerable'
|
2
2
|
|
3
3
|
module Saorin
|
4
|
-
|
4
|
+
module Client
|
5
|
+
include Registerable
|
6
|
+
self.load_path = 'saorin/client'
|
7
|
+
|
5
8
|
class << self
|
6
9
|
def new(options = {}, &block)
|
7
10
|
adapter = options.delete(:adapter) || :faraday
|
8
|
-
adapter_class =
|
11
|
+
adapter_class = guess adapter
|
9
12
|
adapter_class.new options, &block
|
10
13
|
end
|
11
14
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'saorin/request'
|
3
|
+
require 'saorin/response'
|
4
|
+
require 'saorin/client'
|
5
|
+
|
6
|
+
module Saorin
|
7
|
+
module Client
|
8
|
+
module Base
|
9
|
+
CONTENT_TYPE = 'application/json'.freeze
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(method, *args)
|
15
|
+
apply Saorin::Request.new(method, args, :id => seqid!)
|
16
|
+
end
|
17
|
+
|
18
|
+
def notify(method, *args)
|
19
|
+
apply Saorin::Request.new(method, args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def apply(request)
|
23
|
+
response = send_request request.to_json
|
24
|
+
content = process_response response
|
25
|
+
raise content if content.is_a?(Saorin::RPCError)
|
26
|
+
content
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def send_request(content)
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_response(content)
|
36
|
+
response = parse_response content
|
37
|
+
if response.is_a?(::Array)
|
38
|
+
response.map { |res| handle_response res }
|
39
|
+
else
|
40
|
+
handle_response response
|
41
|
+
end
|
42
|
+
rescue Saorin::InvalidResponse => e
|
43
|
+
raise e
|
44
|
+
rescue => e
|
45
|
+
p e
|
46
|
+
print e.backtrace.join("\t\n")
|
47
|
+
raise Saorin::InvalidResponse, e.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_response(content)
|
51
|
+
MultiJson.decode content
|
52
|
+
rescue MultiJson::LoadError => e
|
53
|
+
raise Saorin::InvalidResponse, e.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_content(response)
|
57
|
+
return nil if response.nil?
|
58
|
+
if response.error?
|
59
|
+
code, message, data = response.error.values_at('code', 'message', 'data')
|
60
|
+
error_class = Saorin.code_to_error code
|
61
|
+
raise Error, 'unknown error code' unless error_class
|
62
|
+
error_class.new message, :code => code, :data => data
|
63
|
+
else
|
64
|
+
response.result
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def handle_response(hash)
|
69
|
+
return nil if hash.nil?
|
70
|
+
response = Response.from_hash(hash)
|
71
|
+
response.validate
|
72
|
+
to_content response
|
73
|
+
end
|
74
|
+
|
75
|
+
def seqid
|
76
|
+
@@seqid ||= 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def seqid=(value)
|
80
|
+
@@seqid = value
|
81
|
+
@@seqid = 0 if @@seqid >= (1 << 31)
|
82
|
+
@@seqid
|
83
|
+
end
|
84
|
+
|
85
|
+
def seqid!
|
86
|
+
id = self.seqid
|
87
|
+
self.seqid += 1
|
88
|
+
id
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'saorin/client/base'
|
2
|
+
require 'faraday'
|
3
|
+
|
4
|
+
module Saorin
|
5
|
+
module Client
|
6
|
+
class Faraday
|
7
|
+
include Base
|
8
|
+
|
9
|
+
attr_reader :connection
|
10
|
+
|
11
|
+
def initialize(options = {}, &block)
|
12
|
+
super options
|
13
|
+
|
14
|
+
@connection = ::Faraday::Connection.new(options) do |builder|
|
15
|
+
builder.adapter ::Faraday.default_adapter
|
16
|
+
builder.response :raise_error
|
17
|
+
block.call builder if block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_request(content)
|
22
|
+
response = @connection.post do |req|
|
23
|
+
req.headers[:content_type] = CONTENT_TYPE
|
24
|
+
req.body = content
|
25
|
+
end
|
26
|
+
response.body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
register :faraday, Faraday
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'saorin/error'
|
2
|
+
|
3
|
+
module Saorin
|
4
|
+
module Registerable
|
5
|
+
class << self
|
6
|
+
def included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
attr_accessor :load_path
|
13
|
+
|
14
|
+
def adapters
|
15
|
+
@adapters ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def register(key, adapter)
|
19
|
+
adapters[key.to_s] = adapter
|
20
|
+
end
|
21
|
+
|
22
|
+
def guess(key)
|
23
|
+
key = key.to_s
|
24
|
+
require "#{load_path}/#{key}"
|
25
|
+
adapter = adapters[key]
|
26
|
+
raise AdapterNotFound, key unless adapter
|
27
|
+
adapter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/saorin/server.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
require 'saorin/
|
1
|
+
require 'saorin/registerable'
|
2
2
|
|
3
3
|
module Saorin
|
4
|
-
|
4
|
+
module Server
|
5
|
+
include Registerable
|
6
|
+
self.load_path = 'saorin/server'
|
7
|
+
|
5
8
|
class << self
|
6
9
|
def new(handler, options = {}, &block)
|
7
10
|
adapter = options.delete(:adapter) || :rack
|
8
|
-
adapter_class =
|
11
|
+
adapter_class = guess adapter
|
9
12
|
adapter_class.new handler, options, &block
|
10
13
|
end
|
11
|
-
|
12
14
|
alias_method :start, :new
|
13
15
|
end
|
14
16
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'saorin/error'
|
2
|
+
require 'saorin/request'
|
3
|
+
require 'saorin/response'
|
4
|
+
require 'saorin/server'
|
5
|
+
|
6
|
+
module Saorin
|
7
|
+
module Server
|
8
|
+
module Base
|
9
|
+
attr_reader :handler, :allowed_methods
|
10
|
+
|
11
|
+
def initialize(handler, options = {})
|
12
|
+
@handler = handler
|
13
|
+
@allowed_methods = options[:allowed_methods] || handler.public_methods(false)
|
14
|
+
@allowed_methods.map! { |m| m.to_s }
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_request(content)
|
18
|
+
response = begin
|
19
|
+
request = parse_request content
|
20
|
+
if request.is_a?(::Array)
|
21
|
+
raise Saorin::InvalidRequest if request.empty?
|
22
|
+
responses = request.map { |req| handle_request(req) }
|
23
|
+
responses.compact!
|
24
|
+
responses.empty? ? nil : responses
|
25
|
+
else
|
26
|
+
handle_request(request)
|
27
|
+
end
|
28
|
+
rescue Saorin::Error => e
|
29
|
+
Response.new(:error => e)
|
30
|
+
end
|
31
|
+
|
32
|
+
response && MultiJson.dump(response)
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_request(content)
|
36
|
+
MultiJson.decode content
|
37
|
+
rescue MultiJson::LoadError
|
38
|
+
raise Saorin::ParseError
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_request(hash)
|
42
|
+
begin
|
43
|
+
request = Request.from_hash(hash)
|
44
|
+
request.validate
|
45
|
+
dispatch_request_with_trap_notification request
|
46
|
+
rescue Saorin::InvalidRequest => e
|
47
|
+
Response.new(:error => e)
|
48
|
+
rescue Saorin::Error => e
|
49
|
+
Response.new(:error => e, :id => request.id)
|
50
|
+
rescue Exception => e
|
51
|
+
options = {:error => Saorin::InternalError.new}
|
52
|
+
options[:id] = request.id if request
|
53
|
+
Response.new(options)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def dispatch_request_with_trap_notification(request)
|
58
|
+
result = dispatch_request request
|
59
|
+
Response.new(:result => result, :id => request.id)
|
60
|
+
ensure
|
61
|
+
return nil if request.notify?
|
62
|
+
end
|
63
|
+
|
64
|
+
def dispatch_request(request)
|
65
|
+
method = request.method.to_s
|
66
|
+
params = request.params || []
|
67
|
+
|
68
|
+
unless @allowed_methods.include?(method) && @handler.respond_to?(method)
|
69
|
+
raise Saorin::MethodNotFound
|
70
|
+
end
|
71
|
+
|
72
|
+
begin
|
73
|
+
if params.is_a?(::Hash)
|
74
|
+
@handler.__send__ method, params
|
75
|
+
else
|
76
|
+
@handler.__send__ method, *params
|
77
|
+
end
|
78
|
+
rescue ArgumentError
|
79
|
+
raise Saorin::InvalidParams
|
80
|
+
rescue Exception => e
|
81
|
+
raise Saorin::ServerError, e
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'saorin/server/base'
|
2
|
+
require 'rack'
|
3
|
+
|
4
|
+
module Saorin
|
5
|
+
module Server
|
6
|
+
class Rack
|
7
|
+
include Base
|
8
|
+
|
9
|
+
DEFAULT_HEADERS = {
|
10
|
+
'Content-Type' => 'application/json'
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def initialize(handler, options = {}, &block)
|
14
|
+
super handler, options
|
15
|
+
|
16
|
+
::Rack::Server.start({
|
17
|
+
:app => self,
|
18
|
+
:Host => options[:host],
|
19
|
+
:Port => options[:port],
|
20
|
+
}.merge(options))
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(env)
|
24
|
+
request = ::Rack::Request.new(env)
|
25
|
+
response = ::Rack::Response.new([], 200, DEFAULT_HEADERS.dup)
|
26
|
+
response.write process_request(request.body.read) if request.post?
|
27
|
+
response.finish
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
register :rack, Rack
|
32
|
+
end
|
33
|
+
end
|
data/lib/saorin/version.rb
CHANGED
data/saorin.gemspec
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'saorin/
|
2
|
+
require 'saorin/server/base'
|
3
3
|
|
4
|
-
describe Saorin::
|
4
|
+
describe Saorin::Server::Base do
|
5
5
|
it_should_behave_like 'rpc call' do
|
6
6
|
let(:process) do
|
7
7
|
handler = Saorin::Test::Handler.new
|
8
|
-
|
8
|
+
class VanillaServer
|
9
|
+
include Saorin::Server::Base
|
10
|
+
end
|
11
|
+
server = VanillaServer.new handler
|
9
12
|
proc do |input|
|
10
13
|
server.process_request input
|
11
14
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saorin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -75,22 +75,6 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: reel
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ! '>='
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
94
78
|
- !ruby/object:Gem::Dependency
|
95
79
|
name: faraday
|
96
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,30 +105,24 @@ files:
|
|
121
105
|
- README.md
|
122
106
|
- Rakefile
|
123
107
|
- lib/saorin.rb
|
124
|
-
- lib/saorin/adapters.rb
|
125
|
-
- lib/saorin/adapters/clients.rb
|
126
|
-
- lib/saorin/adapters/clients/base.rb
|
127
|
-
- lib/saorin/adapters/clients/faraday.rb
|
128
|
-
- lib/saorin/adapters/registerable.rb
|
129
|
-
- lib/saorin/adapters/servers.rb
|
130
|
-
- lib/saorin/adapters/servers/base.rb
|
131
|
-
- lib/saorin/adapters/servers/rack.rb
|
132
|
-
- lib/saorin/adapters/servers/reel.rb
|
133
108
|
- lib/saorin/client.rb
|
109
|
+
- lib/saorin/client/base.rb
|
110
|
+
- lib/saorin/client/faraday.rb
|
134
111
|
- lib/saorin/error.rb
|
112
|
+
- lib/saorin/registerable.rb
|
135
113
|
- lib/saorin/request.rb
|
136
114
|
- lib/saorin/response.rb
|
137
115
|
- lib/saorin/server.rb
|
116
|
+
- lib/saorin/server/base.rb
|
117
|
+
- lib/saorin/server/rack.rb
|
138
118
|
- lib/saorin/test.rb
|
139
119
|
- lib/saorin/utility.rb
|
140
120
|
- lib/saorin/version.rb
|
141
121
|
- saorin.gemspec
|
142
|
-
- server.rb
|
143
|
-
- spec/adapter/base_spec.rb
|
144
|
-
- spec/adapter/servers/rack_spec.rb
|
145
|
-
- spec/adapter/servers/reel_spec.rb
|
146
122
|
- spec/request_spec.rb
|
147
123
|
- spec/response_spec.rb
|
124
|
+
- spec/server/base_spec.rb
|
125
|
+
- spec/server/rack_spec.rb
|
148
126
|
- spec/spec_helper.rb
|
149
127
|
- spec/support/rpc_call.rb
|
150
128
|
- spec/support/utils.rb
|
@@ -162,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
140
|
version: '0'
|
163
141
|
segments:
|
164
142
|
- 0
|
165
|
-
hash:
|
143
|
+
hash: 926844584898114179
|
166
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
145
|
none: false
|
168
146
|
requirements:
|
@@ -171,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
149
|
version: '0'
|
172
150
|
segments:
|
173
151
|
- 0
|
174
|
-
hash:
|
152
|
+
hash: 926844584898114179
|
175
153
|
requirements: []
|
176
154
|
rubyforge_project:
|
177
155
|
rubygems_version: 1.8.24
|
@@ -179,11 +157,10 @@ signing_key:
|
|
179
157
|
specification_version: 3
|
180
158
|
summary: JSON-RPC 2.0 server and client implementation for any protocols
|
181
159
|
test_files:
|
182
|
-
- spec/adapter/base_spec.rb
|
183
|
-
- spec/adapter/servers/rack_spec.rb
|
184
|
-
- spec/adapter/servers/reel_spec.rb
|
185
160
|
- spec/request_spec.rb
|
186
161
|
- spec/response_spec.rb
|
162
|
+
- spec/server/base_spec.rb
|
163
|
+
- spec/server/rack_spec.rb
|
187
164
|
- spec/spec_helper.rb
|
188
165
|
- spec/support/rpc_call.rb
|
189
166
|
- spec/support/utils.rb
|
data/lib/saorin/adapters.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'saorin/request'
|
3
|
-
require 'saorin/response'
|
4
|
-
require 'saorin/adapters/clients'
|
5
|
-
|
6
|
-
module Saorin
|
7
|
-
module Adapters
|
8
|
-
module Clients
|
9
|
-
class Base
|
10
|
-
CONTENT_TYPE = 'application/json'.freeze
|
11
|
-
|
12
|
-
def initialize(options = {})
|
13
|
-
end
|
14
|
-
|
15
|
-
def call(method, *args)
|
16
|
-
apply Saorin::Request.new(method, args, :id => seqid!)
|
17
|
-
end
|
18
|
-
|
19
|
-
def notify(method, *args)
|
20
|
-
apply Saorin::Request.new(method, args)
|
21
|
-
end
|
22
|
-
|
23
|
-
def apply(request)
|
24
|
-
response = send_request request.to_json
|
25
|
-
content = process_response response
|
26
|
-
raise content if content.is_a?(Saorin::RPCError)
|
27
|
-
content
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
def send_request(content)
|
33
|
-
raise NotImplementedError
|
34
|
-
end
|
35
|
-
|
36
|
-
def process_response(content)
|
37
|
-
response = parse_response content
|
38
|
-
if response.is_a?(::Array)
|
39
|
-
response.map { |res| handle_response res }
|
40
|
-
else
|
41
|
-
handle_response response
|
42
|
-
end
|
43
|
-
rescue Saorin::InvalidResponse => e
|
44
|
-
raise e
|
45
|
-
rescue => e
|
46
|
-
p e
|
47
|
-
print e.backtrace.join("\t\n")
|
48
|
-
raise Saorin::InvalidResponse, e.to_s
|
49
|
-
end
|
50
|
-
|
51
|
-
def parse_response(content)
|
52
|
-
MultiJson.decode content
|
53
|
-
rescue MultiJson::LoadError => e
|
54
|
-
raise Saorin::InvalidResponse, e.to_s
|
55
|
-
end
|
56
|
-
|
57
|
-
def to_content(response)
|
58
|
-
return nil if response.nil?
|
59
|
-
if response.error?
|
60
|
-
code, message, data = response.error.values_at('code', 'message', 'data')
|
61
|
-
error_class = Saorin.code_to_error code
|
62
|
-
raise Error, 'unknown error code' unless error_class
|
63
|
-
error_class.new message, :code => code, :data => data
|
64
|
-
else
|
65
|
-
response.result
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def handle_response(hash)
|
70
|
-
return nil if hash.nil?
|
71
|
-
response = Response.from_hash(hash)
|
72
|
-
response.validate
|
73
|
-
to_content response
|
74
|
-
end
|
75
|
-
|
76
|
-
def seqid
|
77
|
-
@@seqid ||= 0
|
78
|
-
end
|
79
|
-
|
80
|
-
def seqid=(value)
|
81
|
-
@@seqid = value
|
82
|
-
@@seqid = 0 if @@seqid >= (1 << 31)
|
83
|
-
@@seqid
|
84
|
-
end
|
85
|
-
|
86
|
-
def seqid!
|
87
|
-
id = self.seqid
|
88
|
-
self.seqid += 1
|
89
|
-
id
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'saorin/adapters/clients/base'
|
2
|
-
require 'faraday'
|
3
|
-
|
4
|
-
module Saorin
|
5
|
-
module Adapters
|
6
|
-
module Clients
|
7
|
-
class Faraday < Base
|
8
|
-
attr_reader :connection
|
9
|
-
|
10
|
-
def initialize(options = {}, &block)
|
11
|
-
super options
|
12
|
-
|
13
|
-
@connection = ::Faraday::Connection.new(options) do |builder|
|
14
|
-
builder.adapter ::Faraday.default_adapter
|
15
|
-
builder.response :raise_error
|
16
|
-
block.call builder if block
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def send_request(content)
|
21
|
-
response = @connection.post do |req|
|
22
|
-
req.headers[:content_type] = CONTENT_TYPE
|
23
|
-
req.body = content
|
24
|
-
end
|
25
|
-
response.body
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
register :faraday, Faraday
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'saorin/error'
|
2
|
-
|
3
|
-
module Saorin
|
4
|
-
module Adapters
|
5
|
-
module Registerable
|
6
|
-
class << self
|
7
|
-
def included(base)
|
8
|
-
base.extend ClassMethods
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
attr_accessor :load_path
|
14
|
-
|
15
|
-
def adapters
|
16
|
-
@adapters ||= {}
|
17
|
-
end
|
18
|
-
|
19
|
-
def register(key, adapter)
|
20
|
-
adapters[key.to_s] = adapter
|
21
|
-
end
|
22
|
-
|
23
|
-
def guess(key)
|
24
|
-
key = key.to_s
|
25
|
-
require "#{load_path}/#{key}"
|
26
|
-
adapter = adapters[key]
|
27
|
-
raise AdapterNotFound, key unless adapter
|
28
|
-
adapter
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'saorin/error'
|
2
|
-
require 'saorin/request'
|
3
|
-
require 'saorin/response'
|
4
|
-
require 'saorin/adapters/servers'
|
5
|
-
|
6
|
-
module Saorin
|
7
|
-
module Adapters
|
8
|
-
module Servers
|
9
|
-
class Base
|
10
|
-
attr_reader :handler, :allowed_methods
|
11
|
-
|
12
|
-
def initialize(handler, options = {})
|
13
|
-
@handler = handler
|
14
|
-
@allowed_methods = options[:allowed_methods] || handler.public_methods(false)
|
15
|
-
@allowed_methods.map! { |m| m.to_s }
|
16
|
-
end
|
17
|
-
|
18
|
-
def process_request(content)
|
19
|
-
response = begin
|
20
|
-
request = parse_request content
|
21
|
-
if request.is_a?(::Array)
|
22
|
-
raise Saorin::InvalidRequest if request.empty?
|
23
|
-
responses = request.map { |req| handle_request(req) }
|
24
|
-
responses.compact!
|
25
|
-
responses.empty? ? nil : responses
|
26
|
-
else
|
27
|
-
handle_request(request)
|
28
|
-
end
|
29
|
-
rescue Saorin::Error => e
|
30
|
-
Response.new(:error => e)
|
31
|
-
end
|
32
|
-
|
33
|
-
response && MultiJson.dump(response)
|
34
|
-
end
|
35
|
-
|
36
|
-
def parse_request(content)
|
37
|
-
MultiJson.decode content
|
38
|
-
rescue MultiJson::LoadError
|
39
|
-
raise Saorin::ParseError
|
40
|
-
end
|
41
|
-
|
42
|
-
def handle_request(hash)
|
43
|
-
begin
|
44
|
-
request = Request.from_hash(hash)
|
45
|
-
request.validate
|
46
|
-
dispatch_request_with_trap_notification request
|
47
|
-
rescue Saorin::InvalidRequest => e
|
48
|
-
Response.new(:error => e)
|
49
|
-
rescue Saorin::Error => e
|
50
|
-
Response.new(:error => e, :id => request.id)
|
51
|
-
rescue Exception => e
|
52
|
-
options = {:error => Saorin::InternalError.new}
|
53
|
-
options[:id] = request.id if request
|
54
|
-
Response.new(options)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def dispatch_request_with_trap_notification(request)
|
59
|
-
result = dispatch_request request
|
60
|
-
Response.new(:result => result, :id => request.id)
|
61
|
-
ensure
|
62
|
-
return nil if request.notify?
|
63
|
-
end
|
64
|
-
|
65
|
-
def dispatch_request(request)
|
66
|
-
method = request.method.to_s
|
67
|
-
params = request.params || []
|
68
|
-
|
69
|
-
unless @allowed_methods.include?(method) && @handler.respond_to?(method)
|
70
|
-
raise Saorin::MethodNotFound
|
71
|
-
end
|
72
|
-
|
73
|
-
begin
|
74
|
-
if params.is_a?(::Hash)
|
75
|
-
@handler.__send__ method, params
|
76
|
-
else
|
77
|
-
@handler.__send__ method, *params
|
78
|
-
end
|
79
|
-
rescue ArgumentError
|
80
|
-
raise Saorin::InvalidParams
|
81
|
-
rescue Exception => e
|
82
|
-
raise Saorin::ServerError, e
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'saorin/adapters/servers/base'
|
2
|
-
require 'rack'
|
3
|
-
|
4
|
-
module Saorin
|
5
|
-
module Adapters
|
6
|
-
module Servers
|
7
|
-
class Rack < Base
|
8
|
-
DEFAULT_HEADERS = {
|
9
|
-
'Content-Type' => 'application/json'
|
10
|
-
}.freeze
|
11
|
-
|
12
|
-
def initialize(handler, options = {}, &block)
|
13
|
-
super handler, options
|
14
|
-
|
15
|
-
::Rack::Server.start({
|
16
|
-
:app => self,
|
17
|
-
:Host => options[:host],
|
18
|
-
:Port => options[:port],
|
19
|
-
}.merge(options))
|
20
|
-
end
|
21
|
-
|
22
|
-
def call(env)
|
23
|
-
request = ::Rack::Request.new(env)
|
24
|
-
response = ::Rack::Response.new([], 200, DEFAULT_HEADERS.dup)
|
25
|
-
response.write process_request(request.body.read) if request.post?
|
26
|
-
response.finish
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
register :rack, Rack
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'saorin/adapters/servers/base'
|
2
|
-
require 'reel'
|
3
|
-
|
4
|
-
module Saorin
|
5
|
-
module Adapters
|
6
|
-
module Servers
|
7
|
-
class Reel < Base
|
8
|
-
DEFAULT_HEADERS = {
|
9
|
-
'Content-Type' => 'application/json'
|
10
|
-
}.freeze
|
11
|
-
|
12
|
-
attr_reader :server
|
13
|
-
|
14
|
-
def initialize(handler, options = {}, &block)
|
15
|
-
super handler, options
|
16
|
-
|
17
|
-
@server = ::Reel::Server.supervise(options[:host], options[:port], &method(:process))
|
18
|
-
trap(:INT) { @server.terminate; exit }
|
19
|
-
sleep unless options[:nonblock]
|
20
|
-
end
|
21
|
-
|
22
|
-
def process(connection)
|
23
|
-
while request = connection.request
|
24
|
-
case request
|
25
|
-
when ::Reel::Request
|
26
|
-
response_body = process_request(request.body) if request.method.to_s.upcase == 'POST'
|
27
|
-
response_body ||= ''
|
28
|
-
request.respond :ok, DEFAULT_HEADERS.dup, response_body
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
register :reel, Reel
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/server.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# -*- encoding: utf-8 -*-
|
3
|
-
require 'saorin'
|
4
|
-
|
5
|
-
class Handler
|
6
|
-
def log(tag, time, record)
|
7
|
-
p [tag, time, record]
|
8
|
-
nil
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
Saorin::Server.start Handler.new, :host => 'localhost', :port => 25252, :adapter => :reel
|
13
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'saorin/test'
|
3
|
-
require 'saorin/adapters/servers/reel'
|
4
|
-
|
5
|
-
describe Saorin::Adapters::Servers::Reel do
|
6
|
-
include Saorin::Test
|
7
|
-
|
8
|
-
let(:server_adapter) { :reel }
|
9
|
-
include_context 'setup rpc server client'
|
10
|
-
it_should_behave_like 'rpc server client'
|
11
|
-
end
|