restful_client 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound.yml +2 -0
- data/.ruby-style.yml +239 -0
- data/.travis.yml +5 -0
- data/Gemfile +2 -1
- data/README.md +10 -10
- data/lib/restful_client.rb +57 -46
- data/lib/restful_client_configuration.rb +12 -14
- data/lib/restful_client_logger.rb +6 -5
- data/lib/restful_client_uri.rb +0 -1
- data/restful_client.gemspec +4 -7
- data/spec/restful_client_spec.rb +191 -160
- data/spec/spec_helper.rb +1 -1
- data/spec/support/test_server.rb +19 -17
- metadata +6 -18
- data/lib/restful_client/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffdd1539730f64064b5e045bf4afcad0374ec2dc
|
4
|
+
data.tar.gz: 3110fcd87794defb963f4214b8164e706bf1cea5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b432086f2e3598fae207ca1a85e56a7c3a74f69194d00b10aa9ed495737c8072452e08d9f0e2c4ef97ff0b0899216400215e350832eb09461b4999013d4510e
|
7
|
+
data.tar.gz: 6aebfaf5672c02e41a1b66d7c884bd0c7c3a404a4b9a678d014ef0f0fef9ae194a46868f69c5a9d4cec2bd078c9eeeab99710dde7d04e49d5f61df336a3000e6
|
data/.hound.yml
ADDED
data/.ruby-style.yml
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "vendor/**/*"
|
4
|
+
- "db/schema.rb"
|
5
|
+
UseCache: false
|
6
|
+
Style/CollectionMethods:
|
7
|
+
Description: Preferred collection methods.
|
8
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
|
9
|
+
Enabled: true
|
10
|
+
PreferredMethods:
|
11
|
+
collect: map
|
12
|
+
collect!: map!
|
13
|
+
find: detect
|
14
|
+
find_all: select
|
15
|
+
reduce: inject
|
16
|
+
Style/DotPosition:
|
17
|
+
Description: Checks the position of the dot in multi-line method calls.
|
18
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
|
19
|
+
Enabled: true
|
20
|
+
EnforcedStyle: trailing
|
21
|
+
SupportedStyles:
|
22
|
+
- leading
|
23
|
+
- trailing
|
24
|
+
Style/FileName:
|
25
|
+
Description: Use snake_case for source file names.
|
26
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
|
27
|
+
Enabled: false
|
28
|
+
Exclude: []
|
29
|
+
Style/GuardClause:
|
30
|
+
Description: Check for conditionals that can be replaced with guard clauses
|
31
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
|
32
|
+
Enabled: false
|
33
|
+
MinBodyLength: 1
|
34
|
+
Style/IfUnlessModifier:
|
35
|
+
Description: Favor modifier if/unless usage when you have a single-line body.
|
36
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
|
37
|
+
Enabled: false
|
38
|
+
MaxLineLength: 80
|
39
|
+
Style/OptionHash:
|
40
|
+
Description: Don't use option hashes when you can use keyword arguments.
|
41
|
+
Enabled: false
|
42
|
+
Style/PercentLiteralDelimiters:
|
43
|
+
Description: Use `%`-literal delimiters consistently
|
44
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
|
45
|
+
Enabled: false
|
46
|
+
PreferredDelimiters:
|
47
|
+
"%": "()"
|
48
|
+
"%i": "()"
|
49
|
+
"%q": "()"
|
50
|
+
"%Q": "()"
|
51
|
+
"%r": "{}"
|
52
|
+
"%s": "()"
|
53
|
+
"%w": "()"
|
54
|
+
"%W": "()"
|
55
|
+
"%x": "()"
|
56
|
+
Style/PredicateName:
|
57
|
+
Description: Check the names of predicate methods.
|
58
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
|
59
|
+
Enabled: true
|
60
|
+
NamePrefix:
|
61
|
+
- is_
|
62
|
+
- has_
|
63
|
+
- have_
|
64
|
+
NamePrefixBlacklist:
|
65
|
+
- is_
|
66
|
+
Exclude:
|
67
|
+
- spec/**/*
|
68
|
+
Style/RaiseArgs:
|
69
|
+
Description: Checks the arguments passed to raise/fail.
|
70
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
|
71
|
+
Enabled: false
|
72
|
+
EnforcedStyle: exploded
|
73
|
+
SupportedStyles:
|
74
|
+
- compact
|
75
|
+
- exploded
|
76
|
+
Style/SignalException:
|
77
|
+
Description: Checks for proper usage of fail and raise.
|
78
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
79
|
+
Enabled: false
|
80
|
+
EnforcedStyle: semantic
|
81
|
+
SupportedStyles:
|
82
|
+
- only_raise
|
83
|
+
- only_fail
|
84
|
+
- semantic
|
85
|
+
Style/SingleLineBlockParams:
|
86
|
+
Description: Enforces the names of some block params.
|
87
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
|
88
|
+
Enabled: false
|
89
|
+
Methods:
|
90
|
+
- reduce:
|
91
|
+
- a
|
92
|
+
- e
|
93
|
+
- inject:
|
94
|
+
- a
|
95
|
+
- e
|
96
|
+
Style/SingleLineMethods:
|
97
|
+
Description: Avoid single-line methods.
|
98
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
|
99
|
+
Enabled: false
|
100
|
+
AllowIfMethodIsEmpty: true
|
101
|
+
Style/StringLiterals:
|
102
|
+
Description: Checks if uses of quotes match the configured preference.
|
103
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
|
104
|
+
Enabled: false
|
105
|
+
EnforcedStyle: double_quotes
|
106
|
+
SupportedStyles:
|
107
|
+
- single_quotes
|
108
|
+
- double_quotes
|
109
|
+
Style/StringLiteralsInInterpolation:
|
110
|
+
Description: Checks if uses of quotes inside expressions in interpolated strings
|
111
|
+
match the configured preference.
|
112
|
+
Enabled: true
|
113
|
+
EnforcedStyle: single_quotes
|
114
|
+
SupportedStyles:
|
115
|
+
- single_quotes
|
116
|
+
- double_quotes
|
117
|
+
Style/TrailingComma:
|
118
|
+
Description: Checks for trailing comma in parameter lists and literals.
|
119
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
|
120
|
+
Enabled: false
|
121
|
+
EnforcedStyleForMultiline: no_comma
|
122
|
+
SupportedStyles:
|
123
|
+
- comma
|
124
|
+
- no_comma
|
125
|
+
Metrics/AbcSize:
|
126
|
+
Description: A calculated magnitude based on number of assignments, branches, and
|
127
|
+
conditions.
|
128
|
+
Enabled: false
|
129
|
+
Max: 15
|
130
|
+
Metrics/ClassLength:
|
131
|
+
Description: Avoid classes longer than 100 lines of code.
|
132
|
+
Enabled: false
|
133
|
+
CountComments: false
|
134
|
+
Max: 100
|
135
|
+
Metrics/LineLength:
|
136
|
+
Max: 130
|
137
|
+
Metrics/ModuleLength:
|
138
|
+
CountComments: false
|
139
|
+
Max: 100
|
140
|
+
Description: Avoid modules longer than 100 lines of code.
|
141
|
+
Enabled: false
|
142
|
+
Metrics/CyclomaticComplexity:
|
143
|
+
Description: A complexity metric that is strongly correlated to the number of test
|
144
|
+
cases needed to validate a method.
|
145
|
+
Enabled: false
|
146
|
+
Max: 6
|
147
|
+
Metrics/MethodLength:
|
148
|
+
Description: Avoid methods longer than 10 lines of code.
|
149
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
150
|
+
Enabled: false
|
151
|
+
CountComments: false
|
152
|
+
Max: 10
|
153
|
+
Metrics/ParameterLists:
|
154
|
+
Description: Avoid parameter lists longer than three or four parameters.
|
155
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
|
156
|
+
Enabled: false
|
157
|
+
Max: 5
|
158
|
+
CountKeywordArgs: true
|
159
|
+
Metrics/PerceivedComplexity:
|
160
|
+
Description: A complexity metric geared towards measuring complexity for a human
|
161
|
+
reader.
|
162
|
+
Enabled: false
|
163
|
+
Max: 7
|
164
|
+
Lint/AssignmentInCondition:
|
165
|
+
Description: Don't use assignment in conditions.
|
166
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
|
167
|
+
Enabled: false
|
168
|
+
AllowSafeAssignment: true
|
169
|
+
Style/InlineComment:
|
170
|
+
Description: Avoid inline comments.
|
171
|
+
Enabled: false
|
172
|
+
Style/AccessorMethodName:
|
173
|
+
Description: Check the naming of accessor methods for get_/set_.
|
174
|
+
Enabled: false
|
175
|
+
Style/Alias:
|
176
|
+
Description: Use alias_method instead of alias.
|
177
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
|
178
|
+
Enabled: false
|
179
|
+
Style/Documentation:
|
180
|
+
Description: Document classes and non-namespace modules.
|
181
|
+
Enabled: false
|
182
|
+
Style/ClassVars:
|
183
|
+
Enabled: false
|
184
|
+
Style/DoubleNegation:
|
185
|
+
Description: Checks for uses of double negation (!!).
|
186
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
|
187
|
+
Enabled: false
|
188
|
+
Style/EachWithObject:
|
189
|
+
Description: Prefer `each_with_object` over `inject` or `reduce`.
|
190
|
+
Enabled: false
|
191
|
+
Style/EmptyLiteral:
|
192
|
+
Description: Prefer literals to Array.new/Hash.new/String.new.
|
193
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
|
194
|
+
Enabled: false
|
195
|
+
Style/ModuleFunction:
|
196
|
+
Description: Checks for usage of `extend self` in modules.
|
197
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
|
198
|
+
Enabled: false
|
199
|
+
Style/OneLineConditional:
|
200
|
+
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
|
201
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
|
202
|
+
Enabled: false
|
203
|
+
Style/PerlBackrefs:
|
204
|
+
Description: Avoid Perl-style regex back references.
|
205
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
|
206
|
+
Enabled: false
|
207
|
+
Style/Send:
|
208
|
+
Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
|
209
|
+
may overlap with existing methods.
|
210
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
|
211
|
+
Enabled: false
|
212
|
+
Style/GlobalVars:
|
213
|
+
Enabled: false
|
214
|
+
Style/SpecialGlobalVars:
|
215
|
+
Description: Avoid Perl-style global variables.
|
216
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
|
217
|
+
Enabled: false
|
218
|
+
Style/VariableInterpolation:
|
219
|
+
Description: Don't interpolate global, instance and class variables directly in
|
220
|
+
strings.
|
221
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
|
222
|
+
Enabled: false
|
223
|
+
Style/WhenThen:
|
224
|
+
Description: Use when x then ... for one-line cases.
|
225
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
|
226
|
+
Enabled: false
|
227
|
+
Lint/EachWithObjectArgument:
|
228
|
+
Description: Check for immutable argument given to each_with_object.
|
229
|
+
Enabled: true
|
230
|
+
Lint/HandleExceptions:
|
231
|
+
Description: Don't suppress exception.
|
232
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
|
233
|
+
Enabled: false
|
234
|
+
Lint/LiteralInCondition:
|
235
|
+
Description: Checks of literals used in conditions.
|
236
|
+
Enabled: false
|
237
|
+
Lint/LiteralInInterpolation:
|
238
|
+
Description: Checks for literals used in interpolation.
|
239
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -2,8 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gem 'thin', '~> 1.6'
|
4
4
|
|
5
|
-
gem 'pry-byebug', '~> 3.
|
5
|
+
gem 'pry-byebug', '~> 3.3.0', {}.merge(ENV['RM_INFO'] ? { require: false } : {})
|
6
6
|
gem 'rspec', '~> 3.1'
|
7
7
|
gem 'rspec-its', '~> 1.1'
|
8
|
+
gem 'rubocop', '~> 0.35.1'
|
8
9
|
|
9
10
|
gemspec
|
data/README.md
CHANGED
@@ -12,8 +12,8 @@ An HTTP framework for micro-services based environment, build on top of [typhoeu
|
|
12
12
|
|
13
13
|
* Clean restful api supporting http verbs (GET/PUT/POST/DELETE)
|
14
14
|
* Manage Failures - set stubs for case of errors and SERVICE_DOWN event from [Jynx](https://github.com/AvnerCohen/service-jynx)
|
15
|
-
*
|
16
|
-
* Build using Typheous, a fast and
|
15
|
+
* Structured and configurable YAML for multiple service end points
|
16
|
+
* Build using Typheous, a fast and robust http client, built on top of libcurl
|
17
17
|
* Configurable timeouts for http request
|
18
18
|
|
19
19
|
## Configuration
|
@@ -38,14 +38,14 @@ production: &production
|
|
38
38
|
|
39
39
|
</pre>
|
40
40
|
|
41
|
-
###
|
41
|
+
### Configuration Flags
|
42
42
|
|
43
|
-
* use_jynx - Remove the integrated jynx-service protection (default: false)
|
44
|
-
* report_method - proc to be executed in the case of error
|
45
|
-
* env_name - environment name (production|staging|development etc..)
|
46
|
-
* config_folder - path to the configuration folder of the restful_services.yml file.
|
47
|
-
* user_agent -
|
48
|
-
* legacy_postfix - Legacy version accessed the restful_services.yml with an additional postfix in the yaml.
|
43
|
+
* :use_jynx - Remove the integrated jynx-service protection (default: false)
|
44
|
+
* :report_method - proc to be executed in the case of error
|
45
|
+
* :env_name - environment name (production|staging|development etc..)
|
46
|
+
* :config_folder - path to the configuration folder of the restful_services.yml file.
|
47
|
+
* :user_agent - HTTP User-Agent agent, to be added to identify caller (users|mobile_service|anyname etc..)
|
48
|
+
* :legacy_postfix - Legacy version accessed the restful_services.yml with an additional postfix in the yaml.
|
49
49
|
|
50
50
|
## Usage
|
51
51
|
|
@@ -123,7 +123,7 @@ Given:
|
|
123
123
|
````
|
124
124
|
<pre>
|
125
125
|
|
126
|
-
RestfulClient.srv_url('
|
126
|
+
RestfulClient.srv_url('users') # ==> http://1.2.3.4:8383/api/v0/
|
127
127
|
</pre>
|
128
128
|
|
129
129
|
## Contributing
|
data/lib/restful_client.rb
CHANGED
@@ -11,11 +11,15 @@ module RestfulClient
|
|
11
11
|
|
12
12
|
class RestError < StandardError; end
|
13
13
|
|
14
|
-
|
14
|
+
class << self
|
15
|
+
attr_writer :configuration, :logger, :timeout_occured_count
|
16
|
+
end
|
17
|
+
@@configuration = nil
|
15
18
|
@@logger = nil
|
16
19
|
@@timeout_occured_count = 0
|
17
20
|
|
18
21
|
SERVER_SIDE_ERRORS_RANGE = 500
|
22
|
+
CLIENT_SIDE_ERRORS_RANGE = 400
|
19
23
|
|
20
24
|
def self.configure
|
21
25
|
@@configuration ||= RestfulClientConfiguration.new
|
@@ -33,52 +37,54 @@ module RestfulClient
|
|
33
37
|
end
|
34
38
|
|
35
39
|
def srv_url(caller)
|
36
|
-
callerr_config(caller)[
|
40
|
+
callerr_config(caller)['url']
|
37
41
|
end
|
38
42
|
|
39
|
-
def get(caller, path, params = {},
|
40
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
41
|
-
headers = {
|
42
|
-
headers.merge!(
|
43
|
-
|
43
|
+
def get(caller, path, params = {}, extra = {}, &on_error_block)
|
44
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
45
|
+
headers = { 'Accept' => 'application/json' }
|
46
|
+
headers.merge!(extra.fetch('headers', {}))
|
47
|
+
request_args = { headers: headers, method: 'GET', timeout: timeout, params: params }.merge(extra.fetch('args', {}))
|
48
|
+
request = Typhoeus::Request.new(url, request_args.merge(extra.fetch('args', {})))
|
44
49
|
run_safe_request(caller, request, true, &on_error_block)
|
45
50
|
end
|
46
51
|
|
47
|
-
def post(caller, path, payload,
|
48
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
49
|
-
headers, payload_as_str = prepare_payload_with_headers(payload,
|
50
|
-
|
52
|
+
def post(caller, path, payload, extra = {}, &on_error_block)
|
53
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
54
|
+
headers, payload_as_str = prepare_payload_with_headers(payload, extra.fetch('headers', {}))
|
55
|
+
request_args = { headers: headers, method: 'POST', body: payload_as_str, timeout: timeout }
|
56
|
+
request = Typhoeus::Request.new(url, request_args.merge(extra.fetch('args', {})))
|
51
57
|
run_safe_request(caller, request, false, &on_error_block)
|
52
58
|
end
|
53
59
|
|
54
60
|
def post_raw(caller, path, payload, custom_timeout = timeout, &on_error_block)
|
55
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
61
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
56
62
|
request = Typhoeus::Request.new(url, method: 'POST', body: payload, timeout: custom_timeout)
|
57
63
|
run_safe_request(caller, request, false, &on_error_block)
|
58
64
|
end
|
59
65
|
|
60
|
-
def delete(caller, path, payload = {},
|
61
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
62
|
-
headers, payload_as_str = prepare_payload_with_headers(payload,
|
63
|
-
|
66
|
+
def delete(caller, path, payload = {}, extra = {}, &on_error_block)
|
67
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
68
|
+
headers, payload_as_str = prepare_payload_with_headers(payload, extra.fetch('headers', {}))
|
69
|
+
request_args = { headers: headers, method: 'DELETE', body: payload_as_str, timeout: timeout }
|
70
|
+
request = Typhoeus::Request.new(url, request_args.merge(extra.fetch('args', {})))
|
64
71
|
run_safe_request(caller, request, true, &on_error_block)
|
65
72
|
end
|
66
73
|
|
67
|
-
def put(caller, path, payload,
|
68
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
69
|
-
headers, payload_as_str = prepare_payload_with_headers(payload,
|
74
|
+
def put(caller, path, payload, extra = {}, &on_error_block)
|
75
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
76
|
+
headers, payload_as_str = prepare_payload_with_headers(payload, extra.fetch('headers', {}))
|
70
77
|
request = Typhoeus::Request.new(url, headers: headers, method: 'PUT', body: payload_as_str, timeout: timeout)
|
71
78
|
run_safe_request(caller, request, false, &on_error_block)
|
72
79
|
end
|
73
80
|
|
74
81
|
def callerr_config(caller)
|
75
82
|
caller_setup = configuration.data["#{caller}#{legacy_postfix}"]
|
76
|
-
|
83
|
+
fail "Couldn't find ['#{caller}#{legacy_postfix}'] in the configuration YAML !!" unless caller_setup
|
77
84
|
caller_setup
|
78
85
|
end
|
79
86
|
|
80
87
|
def run_safe_request(caller, request, retry_if_needed, &on_error_block)
|
81
|
-
|
82
88
|
@@timeout_occured_count = 0
|
83
89
|
if !use_jynx?
|
84
90
|
response = run_request(request.dup, __method__, false)
|
@@ -94,39 +100,43 @@ module RestfulClient
|
|
94
100
|
response
|
95
101
|
rescue => e
|
96
102
|
res = ServiceJynx.failure!(caller) if use_jynx?
|
97
|
-
|
103
|
+
|
104
|
+
if res == :WENT_DOWN
|
105
|
+
report_method.call('ServiceJynx', "Service #{caller} was taken down as a result of exception", e)
|
106
|
+
end
|
107
|
+
|
98
108
|
on_error_block.call("Exception in #{caller} execution - #{e.message}") if on_error_block
|
99
109
|
end
|
100
110
|
|
101
111
|
def run_request(request, method, retry_if_needed)
|
102
112
|
logger.debug { "#{__method__} :: Request :: #{request.inspect}" }
|
103
|
-
request.options[:headers].merge!(
|
104
|
-
request.options[:headers].merge!(
|
113
|
+
request.options[:headers].merge!('X-Forwarded-For' => $client_ip) if $client_ip
|
114
|
+
request.options[:headers].merge!('User-Agent' => user_agent)
|
105
115
|
request.on_complete do |response|
|
106
|
-
#200, OK
|
116
|
+
# 200, OK
|
107
117
|
if response.success?
|
108
118
|
logger.debug { "Success in #{method} :: Code: #{response.response_code}, #{response.body}" }
|
109
|
-
return
|
119
|
+
return '' if response.body.empty?
|
110
120
|
begin
|
111
121
|
return JSON.parse(response.body)
|
112
122
|
rescue => e
|
113
|
-
logger.error { "Response from #{response.effective_url} is not a valid json - [#{response.body}]"}
|
123
|
+
logger.error { "Response from #{response.effective_url} is not a valid json - [#{response.body}]" }
|
114
124
|
raise e
|
115
125
|
end
|
116
|
-
#Timeout occured
|
126
|
+
# Timeout occured
|
117
127
|
elsif response.timed_out?
|
118
|
-
@@timeout_occured_count
|
128
|
+
@@timeout_occured_count += 1
|
119
129
|
skip_raise = (retry_if_needed && @@timeout_occured_count <= retries)
|
120
130
|
|
121
|
-
error_type =
|
131
|
+
error_type = 'TimeoutOccured'
|
122
132
|
error_description = prettify_logger(error_type, request, response)
|
123
133
|
logger.error { "Time out in #{method} for: #{error_description}" }
|
124
134
|
|
125
135
|
exception = RuntimeError.new(error_description)
|
126
136
|
exception.set_backtrace(caller)
|
127
|
-
report_method.call(
|
137
|
+
report_method.call('RestError', error_description, exception)
|
128
138
|
|
129
|
-
|
139
|
+
fail RestError.new(response.return_code.to_sym) unless skip_raise
|
130
140
|
# Could not get an http response, something's wrong.
|
131
141
|
elsif response.code == 0
|
132
142
|
|
@@ -136,8 +146,8 @@ module RestfulClient
|
|
136
146
|
|
137
147
|
exception = RuntimeError.new(error_description)
|
138
148
|
exception.set_backtrace(caller)
|
139
|
-
report_method.call(
|
140
|
-
|
149
|
+
report_method.call('RestError', error_description, exception)
|
150
|
+
fail RestError.new(error_type)
|
141
151
|
# Received a non-successful http response.
|
142
152
|
elsif response.code >= SERVER_SIDE_ERRORS_RANGE
|
143
153
|
|
@@ -145,16 +155,17 @@ module RestfulClient
|
|
145
155
|
error_description = prettify_logger(error_type, request, response)
|
146
156
|
logger.error { "#{error_type} #{response.code}/#{response.return_code} for: #{error_description}" }
|
147
157
|
|
148
|
-
report_method.call("RestError", error_description, exception)
|
149
158
|
exception = RuntimeError.new(error_description)
|
150
|
-
|
151
159
|
exception.set_backtrace(caller)
|
160
|
+
report_method.call('RestError', error_description, exception)
|
152
161
|
|
153
|
-
|
162
|
+
fail RestError.new(error_type)
|
163
|
+
elsif response.code.between?(CLIENT_SIDE_ERRORS_RANGE, (SERVER_SIDE_ERRORS_RANGE - 1))
|
164
|
+
logger.error { "#{error_type} #{response.code}/#{response.return_code} for: #{error_description}" }
|
165
|
+
return ''
|
154
166
|
else
|
155
167
|
|
156
|
-
|
157
|
-
|
168
|
+
fail RestError.new(:BadReturnCode)
|
158
169
|
end
|
159
170
|
end
|
160
171
|
request.run
|
@@ -162,9 +173,9 @@ module RestfulClient
|
|
162
173
|
|
163
174
|
def prepare_payload_with_headers(payload, custom_headers)
|
164
175
|
headers = {}
|
165
|
-
if payload.is_a?(Hash)
|
176
|
+
if payload.is_a?(Hash) && payload.any?
|
166
177
|
payload_as_str = payload.to_json(root: false)
|
167
|
-
headers.merge!(
|
178
|
+
headers.merge!('Content-Type' => 'application/json')
|
168
179
|
else
|
169
180
|
payload_as_str = payload
|
170
181
|
end
|
@@ -174,9 +185,9 @@ module RestfulClient
|
|
174
185
|
[headers, payload_as_str]
|
175
186
|
end
|
176
187
|
|
177
|
-
def fake(caller, path,
|
178
|
-
url = RestfulClientUri.uri_join(callerr_config(caller)[
|
179
|
-
Typhoeus.stub(url,
|
188
|
+
def fake(caller, path, _options = {}, &block)
|
189
|
+
url = RestfulClientUri.uri_join(callerr_config(caller)['url'], path)
|
190
|
+
Typhoeus.stub(url, {}, &block)
|
180
191
|
end
|
181
192
|
|
182
193
|
def timeout
|
@@ -205,7 +216,7 @@ module RestfulClient
|
|
205
216
|
|
206
217
|
def prettify_logger(type, request, response)
|
207
218
|
return "#{type} with no request or response." unless request || response
|
208
|
-
"#{type} #{response.code}/#{response.return_code} for: #{request.options.fetch(:method)}
|
219
|
+
"#{type} #{response.code}/#{response.return_code} for: #{request.options.fetch(:method)}, "\
|
220
|
+
"#{request.base_url}, Total time: #{response.total_time} seconds"
|
209
221
|
end
|
210
|
-
|
211
222
|
end
|
@@ -7,31 +7,30 @@ class RestfulClientConfiguration
|
|
7
7
|
DEFAULT_USER_AGENT = 'RestfulClient - https://github.com/AvnerCohen/restful-client'
|
8
8
|
|
9
9
|
def run!
|
10
|
-
|
11
|
-
file_name = [
|
10
|
+
fail 'Configuration directory name must be provided' unless config_folder.class.to_s == 'String'
|
11
|
+
file_name = ['restful_services.yml', 'rest_api.yml'].each do |name|
|
12
12
|
locale_name = File.join(config_folder, name)
|
13
13
|
break locale_name if File.file?(locale_name)
|
14
14
|
end
|
15
15
|
|
16
16
|
## Set Default Values
|
17
|
-
@report_method
|
18
|
-
@timeout
|
19
|
-
@user_agent
|
20
|
-
@retries
|
21
|
-
@legacy_postfix ||=
|
22
|
-
@use_jynx =
|
17
|
+
@report_method ||= proc { |*_args| nil }
|
18
|
+
@timeout ||= DEFAULT_TIMEOUT
|
19
|
+
@user_agent ||= DEFAULT_USER_AGENT
|
20
|
+
@retries ||= DEFAULT_RETRIES
|
21
|
+
@legacy_postfix ||= ''
|
22
|
+
@use_jynx = true if @use_jynx.nil?
|
23
23
|
|
24
24
|
@data = YAML.load(ERB.new(File.read(file_name)).result)[env].each do |name, entry|
|
25
|
-
next unless entry.
|
25
|
+
next unless entry.key?('url')
|
26
26
|
opts = {
|
27
27
|
time_window_in_seconds: entry.fetch(:time_window_in_seconds, 20),
|
28
28
|
max_errors: entry.fetch(:max_errors, 10),
|
29
29
|
grace_period: entry.fetch(:grace_period, 120)
|
30
30
|
}
|
31
31
|
|
32
|
-
ServiceJynx.register!(name.gsub(@legacy_postfix,
|
32
|
+
ServiceJynx.register!(name.gsub(@legacy_postfix, ''), opts) if @use_jynx
|
33
33
|
end
|
34
|
-
|
35
34
|
end
|
36
35
|
|
37
36
|
def reset
|
@@ -45,11 +44,10 @@ class RestfulClientConfiguration
|
|
45
44
|
|
46
45
|
## Dummy method to test reporting phase
|
47
46
|
def report_on
|
48
|
-
@report_method.call(
|
47
|
+
@report_method.call('RestfulClientConfiguration', "Initialized at: #{Time.now.utc}.")
|
49
48
|
end
|
50
49
|
|
51
50
|
def env
|
52
|
-
@env_name ||
|
51
|
+
@env_name || 'default'
|
53
52
|
end
|
54
|
-
|
55
53
|
end
|
@@ -7,17 +7,18 @@ module RestfulClientLogger
|
|
7
7
|
|
8
8
|
def rails_logger
|
9
9
|
(defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
|
10
|
-
|
10
|
+
(defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:debug) && RAILS_DEFAULT_LOGGER)
|
11
11
|
end
|
12
12
|
|
13
13
|
def default_logger
|
14
14
|
require 'logger'
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
alogger = Logger.new(STDOUT)
|
16
|
+
alogger.level = Logger::INFO
|
17
|
+
alogger.datetime_format = '%c'
|
18
|
+
alogger
|
18
19
|
end
|
19
20
|
|
20
21
|
def logger=(logger)
|
21
22
|
@logger = logger
|
22
23
|
end
|
23
|
-
end
|
24
|
+
end
|
data/lib/restful_client_uri.rb
CHANGED
data/restful_client.gemspec
CHANGED
@@ -1,26 +1,23 @@
|
|
1
1
|
lib = File.expand_path('../lib', __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require 'restful_client/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |spec|
|
6
5
|
spec.name = 'restful_client'
|
7
|
-
spec.version =
|
6
|
+
spec.version = '0.3.0'
|
8
7
|
spec.authors = ['Avner Cohen']
|
9
8
|
spec.email = ['israbirding@gmail.com']
|
10
|
-
spec.description =
|
11
|
-
spec.summary =
|
9
|
+
spec.description = 'An HTTP framework for micro-services based environment, build on top of Typheous and Service Jynx'
|
10
|
+
spec.summary = 'An HTTP framework for micro-services based environment'
|
12
11
|
spec.homepage = 'https://github.com/AvnerCohen/restful_client'
|
13
12
|
spec.license = 'MIT'
|
14
13
|
|
15
|
-
spec.files = `git ls-files`.split(
|
14
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
16
15
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
17
|
spec.require_paths = ['lib']
|
19
18
|
|
20
19
|
spec.add_development_dependency 'bundler'
|
21
|
-
spec.add_development_dependency 'rake'
|
22
20
|
|
23
21
|
spec.add_runtime_dependency 'service_jynx'
|
24
22
|
spec.add_runtime_dependency 'typhoeus'
|
25
23
|
end
|
26
|
-
|