dtk-common-core 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,195 @@
1
+ require 'restclient'
2
+ require 'json'
3
+
4
+ module DTK
5
+ module Common
6
+ module ResponseTokens
7
+ StatusOK = "ok"
8
+ StatusNotok = "notok"
9
+ DataField = "data"
10
+ StatusField = "status"
11
+ ErrorsField = "errors"
12
+ ValidationField = "validation"
13
+ ErrorsSubFieldCode = "code"
14
+ ErrorsOriginalException = "original_exception"
15
+ GenericError = "error"
16
+ end
17
+
18
+ class Response < Hash
19
+ include ResponseTokens
20
+ def initialize(hash={})
21
+ super()
22
+ replace(hash)
23
+ end
24
+ def ok?()
25
+ self[StatusField] == StatusOK
26
+ end
27
+
28
+ def validation_response?
29
+ !self[ValidationField].nil?
30
+ end
31
+
32
+ def validation_message
33
+ self[ValidationField]['message']
34
+ end
35
+
36
+ def error_message
37
+ self["errors"] ? (self["errors"].map { |e| e["message"]}).join(', ') : nil
38
+ end
39
+
40
+ def validation_actions
41
+ return self[ValidationField]['actions_needed']
42
+ end
43
+
44
+ def data(*data_keys)
45
+ data = self[DataField]
46
+ case data_keys.size
47
+ when 0 then data
48
+ when 1 then data && data[internal_key_form(data_keys.first)]
49
+ else data_keys.map{|key|data && data[internal_key_form(key)]}.compact
50
+ end
51
+ end
52
+
53
+ def data_hash_form(*data_keys)
54
+ ret = Hash.new
55
+ unless data = self[DataField]
56
+ return ret
57
+ end
58
+
59
+ if data_keys.size == 0
60
+ data.inject(Hash.new){|h,(k,v)|h.merge(external_key_form(k) => v)}
61
+ else
62
+ data_keys.each do |k|
63
+ if v = data[internal_key_form(k)]
64
+ ret.merge!(external_key_form(k) => v)
65
+ end
66
+ end
67
+ ret
68
+ end
69
+ end
70
+
71
+ def set_data(*data_values)
72
+ self[DataField]=data_values
73
+ end
74
+
75
+ def data_ret_and_remove!(*data_keys)
76
+ data = data()
77
+ data_keys.map{|key|data.delete(internal_key_form(key))}
78
+ end
79
+
80
+ def add_data_value!(key,value)
81
+ data()[key.to_s] = value
82
+ self
83
+ end
84
+
85
+ def internal_key_form(key)
86
+ key.to_s
87
+ end
88
+ def external_key_form(key)
89
+ key.to_sym
90
+ end
91
+ private :internal_key_form,:external_key_form
92
+
93
+ module ErrorMixin
94
+ def ok?()
95
+ false
96
+ end
97
+ end
98
+
99
+ class Error < self
100
+ include ErrorMixin
101
+ def initialize(hash={})
102
+ super(hash)
103
+ end
104
+ end
105
+
106
+ class RestClientWrapper
107
+ class << self
108
+ include ResponseTokens
109
+ def get_raw(url,body={},opts={},&block)
110
+ error_handling(opts) do
111
+ url_with_params = generate_query_params_url(url, body)
112
+ raw_response = ::RestClient::Resource.new(url_with_params,opts).get()
113
+ block ? block.call(raw_response) : raw_response
114
+ end
115
+ end
116
+
117
+ def get(url, body={}, opts={})
118
+ get_raw(url,body, opts){|raw_response|Response.new(json_parse_if_needed(raw_response))}
119
+ end
120
+
121
+ def post_raw(url,body={},opts={},&block)
122
+ error_handling(opts) do
123
+ raw_response = ::RestClient::Resource.new(url,opts).post(body)
124
+ block ? block.call(raw_response) : raw_response
125
+ end
126
+ end
127
+
128
+ def delete_raw(url,body={},opts={},&block)
129
+ error_handling(opts) do
130
+ # DELETE method supports only query params
131
+ url_with_params = generate_query_params_url(url, body)
132
+ raw_response = ::RestClient::Resource.new(url_with_params,opts).delete()
133
+ block ? block.call(raw_response) : raw_response
134
+ end
135
+ end
136
+
137
+ def post(url,body={},opts={})
138
+ post_raw(url,body,opts){|raw_response|Response.new(json_parse_if_needed(raw_response))}
139
+ end
140
+
141
+ def delete(url, body={}, opts={})
142
+ delete_raw(url,body,opts){|raw_response|Response.new(json_parse_if_needed(raw_response))}
143
+ end
144
+
145
+ def json_parse_if_needed(item)
146
+ item.kind_of?(String) ? JSON.parse(item) : item
147
+ end
148
+ private
149
+
150
+ def generate_query_params_url(url, params_hash)
151
+ if params_hash.empty?
152
+ return url
153
+ else
154
+ query_params_string = params_hash.map { |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join('&')
155
+ return url.concat('?').concat(query_params_string)
156
+ end
157
+ end
158
+
159
+ def error_handling(opts={},&block)
160
+ begin
161
+ block.call
162
+ rescue ::RestClient::Forbidden => e
163
+ return error_response({ErrorsSubFieldCode => RestClientErrors[e.class.to_s]||GenericError, ErrorsOriginalException => e},opts) unless e.inspect.to_s.include?("PG::Error")
164
+
165
+ errors = {"code" => "pg_error", "message" => e.inspect.to_s.strip, ErrorsOriginalException => e}
166
+ error_response(errors)
167
+ rescue ::RestClient::ServerBrokeConnection,::RestClient::InternalServerError,::RestClient::RequestTimeout,RestClient::Request::Unauthorized, Errno::ECONNREFUSED => e
168
+ error_response({ErrorsSubFieldCode => RestClientErrors[e.class.to_s]||GenericError, ErrorsOriginalException => e},opts)
169
+ rescue ::RestClient::ResourceNotFound => e
170
+ errors = {"code" => RestClientErrors[e.class.to_s], "message" => e.to_s, ErrorsOriginalException => e}
171
+ error_response(errors)
172
+ rescue Exception => e
173
+ error_response({ErrorsSubFieldCode => e.class.to_s, ErrorsOriginalException => e},opts)
174
+ end
175
+ end
176
+
177
+ def error_response(error_or_errors,opts={})
178
+ errors = error_or_errors.kind_of?(Hash) ? [error_or_errors] : error_or_errors
179
+ (opts[:error_response_class]||Error).new(StatusField => StatusNotok, ErrorsField => errors)
180
+ end
181
+
182
+ RestClientErrors = {
183
+ "RestClient::Forbidden" => "forbidden",
184
+ "RestClient::ServerBrokeConnection" => "broken",
185
+ "RestClient::Request::Unauthorized" => "unauthorized",
186
+ "RestClient::InternalServerError" => "internal_server_error",
187
+ "RestClient::RequestTimeout" => "timeout",
188
+ "RestClient::ResourceNotFound" => "resource_not_found",
189
+ "Errno::ECONNREFUSED" => "connection_refused"
190
+ }
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dtk-common-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.6
5
+ platform: ruby
6
+ authors:
7
+ - Rich PELAVIN
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.6.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.6.7
27
+ description: Dtk common repo is core common librabry of dtk, and mostly hold libraries
28
+ used for http communication.
29
+ email:
30
+ - rich@reactor8.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - .gitignore
36
+ - Gemfile
37
+ - LICENSE
38
+ - README.md
39
+ - dtk-common-core.gemspec
40
+ - lib/auxiliary.rb
41
+ - lib/dtk-common-core/version.rb
42
+ - lib/dtk_common_core.rb
43
+ - lib/errors.rb
44
+ - lib/errors/errors.rb
45
+ - lib/errors/rest_error.rb
46
+ - lib/hash_object.rb
47
+ - lib/log.rb
48
+ - lib/response.rb
49
+ homepage: https://github.com/rich-reactor8/dtk-common-repo
50
+ licenses:
51
+ - GPL-3.0
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.1.9
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Common libraries used for DTK CLI client.
73
+ test_files: []