dtk-common-core 0.5.6

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,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: []