rubycent 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +66 -0
- data/.rspec +3 -0
- data/.travis.yml +21 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +344 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/rubycent.rb +52 -0
- data/lib/rubycent/client.rb +375 -0
- data/lib/rubycent/error.rb +9 -0
- data/lib/rubycent/errors/network_error.rb +11 -0
- data/lib/rubycent/errors/request_error.rb +18 -0
- data/lib/rubycent/errors/response_error.rb +17 -0
- data/lib/rubycent/query.rb +65 -0
- data/lib/rubycent/request.rb +117 -0
- data/lib/rubycent/version.rb +5 -0
- data/rubycent.gemspec +45 -0
- metadata +163 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubycent
|
4
|
+
# Rubycent::RequestError
|
5
|
+
#
|
6
|
+
# Raised when request to Centrifugo API failed in some way.
|
7
|
+
#
|
8
|
+
class RequestError < Error
|
9
|
+
attr_reader :message, :status
|
10
|
+
|
11
|
+
def initialize(message, status)
|
12
|
+
@message = message
|
13
|
+
@status = status
|
14
|
+
|
15
|
+
super(message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubycent
|
4
|
+
# Rubycent::ResponseError
|
5
|
+
#
|
6
|
+
# Raised when response from Centrifugo contains any error as result of API command execution.
|
7
|
+
#
|
8
|
+
class ResponseError < Error
|
9
|
+
attr_reader :message, :code
|
10
|
+
|
11
|
+
def initialize(error_data)
|
12
|
+
@message, @code = error_data.values_at('message', 'code')
|
13
|
+
|
14
|
+
super(@message)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
require 'rubycent/request'
|
6
|
+
|
7
|
+
module Rubycent
|
8
|
+
# Rubycent::Query
|
9
|
+
#
|
10
|
+
# Centrifugo API request configuration and execution
|
11
|
+
#
|
12
|
+
class Query
|
13
|
+
attr_reader :client
|
14
|
+
|
15
|
+
# @param client [Rubycent::Client]
|
16
|
+
# Rubycent client that contains all the configuration
|
17
|
+
#
|
18
|
+
def initialize(client)
|
19
|
+
@client = client
|
20
|
+
end
|
21
|
+
|
22
|
+
# Perform centrifugo API call
|
23
|
+
#
|
24
|
+
# @param method [String]
|
25
|
+
# Centrifugo command, represents centrifugo actions such as 'publish', 'broadcast', e.t.c.
|
26
|
+
#
|
27
|
+
# @param data [Hash]
|
28
|
+
# Any data that will be sent as command parameters
|
29
|
+
#
|
30
|
+
# @return [Hash] Parser request responce
|
31
|
+
#
|
32
|
+
# @raise [Rubycent::Error, Rubycent::NetworkError, Rubycent::RequestError, Rubycent::ResponseError]
|
33
|
+
#
|
34
|
+
def execute(method, data)
|
35
|
+
body = dump_body(method, data)
|
36
|
+
|
37
|
+
params = {
|
38
|
+
timeout: client.timeout,
|
39
|
+
open_timeout: client.open_timeout
|
40
|
+
}
|
41
|
+
|
42
|
+
headers = build_headers(client.api_key)
|
43
|
+
endpoint = build_endpoint(client.host, client.port, client.scheme.to_s)
|
44
|
+
|
45
|
+
Rubycent::Request.new(endpoint, params, body, headers).post
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def dump_body(method, params)
|
51
|
+
MultiJson.dump(method: method, params: params)
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_endpoint(host, port, scheme)
|
55
|
+
::URI::Generic.build(scheme: scheme, host: host, port: port, path: '/api').to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_headers(api_key)
|
59
|
+
{
|
60
|
+
'Content-Type' => 'application/json',
|
61
|
+
'Authorization' => "apikey #{api_key}"
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module Rubycent
|
6
|
+
# Rubycent::Request
|
7
|
+
#
|
8
|
+
# Holds request call and response handling logic
|
9
|
+
#
|
10
|
+
class Request
|
11
|
+
attr_accessor :endpoint, :params, :body, :headers
|
12
|
+
|
13
|
+
# @param endpoint [String] Centrifugo API endpoint
|
14
|
+
#
|
15
|
+
# @param params [Hash] Additional params to configure request.
|
16
|
+
#
|
17
|
+
# @option params [Integer] :timeout
|
18
|
+
# Number of seconds to wait for the connection to open.
|
19
|
+
#
|
20
|
+
# @option params [Integer] :open_timeout
|
21
|
+
# Number of seconds to wait for one block to be read.
|
22
|
+
#
|
23
|
+
# @param body [String]
|
24
|
+
# (default: nil) JSON string representing request parameters.
|
25
|
+
#
|
26
|
+
# @param headers [Hash]
|
27
|
+
# (default: {}) Additional HTTP headers(such as Content-Type and Authorization).
|
28
|
+
#
|
29
|
+
def initialize(endpoint, params, body = nil, headers = {})
|
30
|
+
@endpoint = endpoint
|
31
|
+
@params = params
|
32
|
+
@body = body
|
33
|
+
@headers = headers
|
34
|
+
end
|
35
|
+
|
36
|
+
# Perform POST request to centrifugo API
|
37
|
+
#
|
38
|
+
# @raise [Rubycent::Error, Rubycent::NetworkError, Rubycent::RequestError, Rubycent::ResponseError]
|
39
|
+
#
|
40
|
+
# @return [Hash] Parsed response body
|
41
|
+
#
|
42
|
+
def post
|
43
|
+
response = rest_client.post(@endpoint) do |request|
|
44
|
+
configure_request(request: request, body: body, headers: headers)
|
45
|
+
end
|
46
|
+
|
47
|
+
handle_response(response)
|
48
|
+
rescue Faraday::ConnectionFailed => e
|
49
|
+
handle_error(e)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def rest_client
|
55
|
+
Faraday.new do |faraday|
|
56
|
+
faraday.adapter(Rubycent.request_adapter)
|
57
|
+
faraday.headers = @headers
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def configure_request(request: nil, headers: nil, body: nil)
|
62
|
+
return if request.nil?
|
63
|
+
|
64
|
+
request.headers.merge!(headers) if headers
|
65
|
+
request.body = body if body
|
66
|
+
|
67
|
+
request.options.timeout = @params[:timeout]
|
68
|
+
request.options.open_timeout = @params[:open_timeout]
|
69
|
+
end
|
70
|
+
|
71
|
+
def handle_response(response)
|
72
|
+
response.status == 200 ? parse_response(response) : raise_error(response)
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_response(response)
|
76
|
+
MultiJson.load(response.body).tap do |data|
|
77
|
+
raise ResponseError, data['error'] if data.key?('error')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def raise_error(response)
|
82
|
+
status_code = response.status
|
83
|
+
body = response.body
|
84
|
+
|
85
|
+
message = resolve_error_message(status_code, body)
|
86
|
+
|
87
|
+
case status_code
|
88
|
+
when 400..404
|
89
|
+
raise RequestError.new(message, status_code)
|
90
|
+
else
|
91
|
+
raise Error, message
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def resolve_error_message(status, additional_info = nil)
|
96
|
+
error_messages = {
|
97
|
+
400 => "Bad request: #{additional_info}",
|
98
|
+
401 => 'Invalid API key',
|
99
|
+
404 => 'Route not found'
|
100
|
+
}
|
101
|
+
|
102
|
+
error_messages.fetch(status) do
|
103
|
+
"Status: #{status}. Unknown error: #{additional_info}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def handle_error(error)
|
108
|
+
message = "#{error.message} (#{error.class})"
|
109
|
+
|
110
|
+
wrapper = NetworkError.new(message).tap do |w|
|
111
|
+
w.original_error = error
|
112
|
+
end
|
113
|
+
|
114
|
+
raise wrapper
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/rubycent.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rubycent/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'rubycent'
|
9
|
+
spec.version = Rubycent::VERSION
|
10
|
+
spec.authors = ['Warshavski']
|
11
|
+
spec.email = ['p.warshavski@gmail.com']
|
12
|
+
|
13
|
+
spec.summary = 'Ruby client to communicate with Centrifugo v2 HTTP API'
|
14
|
+
spec.description = 'Ruby client to communicate with Centrifugo v2 HTTP API'
|
15
|
+
spec.homepage = 'https://github.com/Warshavski/rubycent'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
20
|
+
if spec.respond_to?(:metadata)
|
21
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
22
|
+
spec.metadata['source_code_uri'] = 'https://github.com/Warshavski/rubycent'
|
23
|
+
else
|
24
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
25
|
+
'public gem pushes.'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Specify which files should be added to the gem when it is released.
|
29
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
31
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
32
|
+
end
|
33
|
+
spec.bindir = 'exe'
|
34
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ['lib']
|
36
|
+
|
37
|
+
spec.add_dependency 'faraday', '~> 0.16.1'
|
38
|
+
spec.add_dependency 'jwt', '~> 2.2.1'
|
39
|
+
spec.add_dependency 'multi_json', '~> 1.13.1'
|
40
|
+
|
41
|
+
spec.add_development_dependency 'bundler'
|
42
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
43
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
44
|
+
spec.add_development_dependency 'webmock', '~> 3.7.5'
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubycent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Warshavski
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-09-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.16.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.16.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: jwt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.13.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.13.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 3.7.5
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 3.7.5
|
111
|
+
description: Ruby client to communicate with Centrifugo v2 HTTP API
|
112
|
+
email:
|
113
|
+
- p.warshavski@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE.txt
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- bin/console
|
126
|
+
- bin/setup
|
127
|
+
- lib/rubycent.rb
|
128
|
+
- lib/rubycent/client.rb
|
129
|
+
- lib/rubycent/error.rb
|
130
|
+
- lib/rubycent/errors/network_error.rb
|
131
|
+
- lib/rubycent/errors/request_error.rb
|
132
|
+
- lib/rubycent/errors/response_error.rb
|
133
|
+
- lib/rubycent/query.rb
|
134
|
+
- lib/rubycent/request.rb
|
135
|
+
- lib/rubycent/version.rb
|
136
|
+
- rubycent.gemspec
|
137
|
+
homepage: https://github.com/Warshavski/rubycent
|
138
|
+
licenses:
|
139
|
+
- MIT
|
140
|
+
metadata:
|
141
|
+
homepage_uri: https://github.com/Warshavski/rubycent
|
142
|
+
source_code_uri: https://github.com/Warshavski/rubycent
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
requirements: []
|
158
|
+
rubyforge_project:
|
159
|
+
rubygems_version: 2.7.6
|
160
|
+
signing_key:
|
161
|
+
specification_version: 4
|
162
|
+
summary: Ruby client to communicate with Centrifugo v2 HTTP API
|
163
|
+
test_files: []
|