datumfactory 0.1.0 → 0.2.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 +4 -4
- data/.rubocop.yml +2 -0
- data/Gemfile.lock +1 -1
- data/datumfactory.gemspec +1 -1
- data/lib/datumfactory.rb +26 -1
- data/lib/datumfactory/config/defaults.rb +21 -0
- data/lib/datumfactory/config/yaml.rb +73 -0
- data/lib/datumfactory/util/config.rb +390 -0
- data/lib/datumfactory/util/http.rb +89 -0
- data/lib/datumfactory/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1011bfbea1d54f85f28c0e299d808028e55aafd45364fb594f3af22e2f8f90af
|
4
|
+
data.tar.gz: 5cdfe12953c2cdd16884b02775aa5e630412fbb491390c54152e16720bb8729d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5faa07f7b5174d0898d461eec68be975083429ab62922d7cae65382103f91214da14b18e0a5338c6e2e4e36d8cdd30b4a33a907116cd7de73289a5ac12ef2621
|
7
|
+
data.tar.gz: ee23e33eae5bf4e54cb3244edeec4604b200480155334967ed96185e169528098bcf5f03cd5b6a6d1c270b0e65e3a35a4daaba465a70f19423daf7bf6eec1c76
|
data/.rubocop.yml
ADDED
data/Gemfile.lock
CHANGED
data/datumfactory.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
24
24
|
end
|
25
|
-
spec.bindir =
|
25
|
+
spec.bindir = 'exe'
|
26
26
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ['lib']
|
28
28
|
|
data/lib/datumfactory.rb
CHANGED
@@ -13,7 +13,32 @@ module Datumfactory
|
|
13
13
|
attr_reader :auth_token
|
14
14
|
|
15
15
|
format :json
|
16
|
-
base_uri
|
16
|
+
base_uri 'datumfactory.com'
|
17
|
+
|
18
|
+
def self.capture_event(container, auth_token, data, title, slug, description = nil)
|
19
|
+
body = {
|
20
|
+
query: {
|
21
|
+
event: {
|
22
|
+
data: data,
|
23
|
+
title: title,
|
24
|
+
description: description,
|
25
|
+
slug: slug
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
options = {
|
31
|
+
headers: {
|
32
|
+
'Content-Type' => 'application/json',
|
33
|
+
'X-API-Key' => auth_token.to_s
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
#options.merge!({ headers: { 'X-API-Key' => auth_token.to_s } })
|
38
|
+
options.merge!(body)
|
39
|
+
base_uri "https://#{container}.datumfactory.com"
|
40
|
+
post('/api/v1/events', options).parsed_response
|
41
|
+
end
|
17
42
|
|
18
43
|
def initialize(site, email, password)
|
19
44
|
self.class.base_uri "#{site}.datumfactory.com"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Datumfactory
|
4
|
+
class Config
|
5
|
+
class Boolean; end
|
6
|
+
|
7
|
+
DEVELOPMENT_ENVIRONMENTS = %w[development test].map(&:freeze).freeze
|
8
|
+
|
9
|
+
DEFAULT_PATHS = ['config/datumfactory.yml'].map(&:freeze).freeze
|
10
|
+
|
11
|
+
OPTIONS = {
|
12
|
+
api_key: {
|
13
|
+
description: 'The API key for your Datumfactory container.',
|
14
|
+
default: nil,
|
15
|
+
type: String
|
16
|
+
}
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
DEFAULTS = Hash[OPTIONS.map{|k,v| [k, v[:default]] }].freeze
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Datumfactory
|
6
|
+
class Config
|
7
|
+
module Yaml
|
8
|
+
DISALLOWED_KEYS = [:'config.path'].freeze
|
9
|
+
|
10
|
+
def self.new(path, env = 'production')
|
11
|
+
path = path.kind_of?(Pathname) ? path : Pathname.new(path)
|
12
|
+
|
13
|
+
if !path.exist?
|
14
|
+
raise ConfigError, "The configuration file #{path} was not found."
|
15
|
+
elsif !path.file?
|
16
|
+
raise ConfigError, "The configuration file #{path} is not a file."
|
17
|
+
elsif !path.readable?
|
18
|
+
raise ConfigError, "The configuration file #{path} is not readable."
|
19
|
+
end
|
20
|
+
|
21
|
+
yaml = load_yaml(path)
|
22
|
+
yaml.merge!(yaml[env]) if yaml[env].kind_of?(Hash)
|
23
|
+
|
24
|
+
dotify_keys(yaml)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_yaml(path)
|
28
|
+
begin
|
29
|
+
yaml = YAML.load(ERB.new(path.read).result)
|
30
|
+
rescue => e
|
31
|
+
config_error = ConfigError.new(e.to_s)
|
32
|
+
|
33
|
+
if e.backtrace
|
34
|
+
backtrace = e.backtrace.map do |line|
|
35
|
+
if line.start_with?('(erb)'.freeze)
|
36
|
+
line.gsub('(erb)'.freeze, path.to_s)
|
37
|
+
else
|
38
|
+
line
|
39
|
+
end
|
40
|
+
end
|
41
|
+
config_error.set_backtrace(backtrace)
|
42
|
+
end
|
43
|
+
|
44
|
+
raise config_error
|
45
|
+
end
|
46
|
+
|
47
|
+
case yaml
|
48
|
+
when Hash
|
49
|
+
yaml
|
50
|
+
when NilClass, FalseClass
|
51
|
+
{}
|
52
|
+
else
|
53
|
+
raise ConfigError, "The configuration file #{path} is invalid."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.dotify_keys(hash, key_prefix = nil)
|
58
|
+
{}.tap do |new_hash|
|
59
|
+
hash.each_pair do |k,v|
|
60
|
+
k = [key_prefix, k].compact.join('.')
|
61
|
+
if v.kind_of?(Hash)
|
62
|
+
new_hash.update(dotify_keys(v, k))
|
63
|
+
else
|
64
|
+
next if DISALLOWED_KEYS.include?(k.to_sym)
|
65
|
+
|
66
|
+
new_hash[k.to_sym] = v
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,390 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'delegate'
|
3
|
+
require 'logger'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
require 'datumfactory/version'
|
8
|
+
require 'datumfactory/backend'
|
9
|
+
require 'datumfactory/config/defaults'
|
10
|
+
require 'datumfactory/util/http'
|
11
|
+
|
12
|
+
module Datumfactory
|
13
|
+
class Config
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
class ConfigError < StandardError; end
|
17
|
+
|
18
|
+
KEY_REPLACEMENT = Regexp.new('[^a-z\d_]', Regexp::IGNORECASE).freeze
|
19
|
+
|
20
|
+
DOTTED_KEY = Regexp.new('\A([^\.]+)\.(.+)\z').freeze
|
21
|
+
|
22
|
+
NOT_BLANK = Regexp.new('\S').freeze
|
23
|
+
|
24
|
+
def initialize(opts = {})
|
25
|
+
@ruby = opts.freeze
|
26
|
+
@env = {}.freeze
|
27
|
+
@yaml = {}.freeze
|
28
|
+
@framework = {}.freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessor :ruby, :env, :yaml, :framework
|
32
|
+
|
33
|
+
def load!(framework: {}, env: ENV)
|
34
|
+
return self if @load
|
35
|
+
|
36
|
+
self.framework = framework.freeze
|
37
|
+
self.env = Env.new(env).freeze
|
38
|
+
load_config_from_disk {|yaml| self.yaml = yaml.freeze }
|
39
|
+
detect_revision!
|
40
|
+
@loaded = true
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def configure
|
45
|
+
new_ruby = Ruby.new(self)
|
46
|
+
yield(new_ruby)
|
47
|
+
self.ruby = ruby.merge(new_ruby).freeze
|
48
|
+
@logger = @backend = nil
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def backtrace_filter(&block)
|
53
|
+
if block_given?
|
54
|
+
warn('DEPRECATED: backtrace_filter is deprecated. Please use before_notify instead. See https://docs.honeybadger.io/ruby/support/v4-upgrade#backtrace_filter')
|
55
|
+
self[:backtrace_filter] = block
|
56
|
+
end
|
57
|
+
|
58
|
+
self[:backtrace_filter]
|
59
|
+
end
|
60
|
+
|
61
|
+
def before_notify_hooks
|
62
|
+
(ruby[:before_notify] || []).clone
|
63
|
+
end
|
64
|
+
|
65
|
+
def exception_filter(&block)
|
66
|
+
if block_given?
|
67
|
+
warn('DEPRECATED: exception_filter is deprecated. Please use before_notify instead. See https://docs.honeybadger.io/ruby/support/v4-upgrade#exception_filter')
|
68
|
+
self[:exception_filter] = block
|
69
|
+
end
|
70
|
+
|
71
|
+
self[:exception_filter]
|
72
|
+
end
|
73
|
+
|
74
|
+
def exception_fingerprint(&block)
|
75
|
+
if block_given?
|
76
|
+
warn('DEPRECATED: exception_fingerprint is deprecated. Please use before_notify instead. See https://docs.honeybadger.io/ruby/support/v4-upgrade#exception_fingerprint')
|
77
|
+
self[:exception_fingerprint] = block
|
78
|
+
end
|
79
|
+
|
80
|
+
self[:exception_fingerprint]
|
81
|
+
end
|
82
|
+
|
83
|
+
def get(key)
|
84
|
+
IVARS.each do |var|
|
85
|
+
source = instance_variable_get(var)
|
86
|
+
if source.has_key?(key)
|
87
|
+
return source[key]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
DEFAULTS[key]
|
92
|
+
end
|
93
|
+
alias [] :get
|
94
|
+
|
95
|
+
def set(key, value)
|
96
|
+
self.ruby = ruby.merge(key => value).freeze
|
97
|
+
@logger = @backend = nil
|
98
|
+
end
|
99
|
+
alias []= :set
|
100
|
+
|
101
|
+
def to_hash(defaults = false)
|
102
|
+
hash = [:@ruby, :@env, :@yaml, :@framework].reverse.reduce({}) do |a,e|
|
103
|
+
a.merge!(instance_variable_get(e))
|
104
|
+
end
|
105
|
+
|
106
|
+
hash = DEFAULTS.merge(hash) if defaults
|
107
|
+
|
108
|
+
undotify_keys(hash.select {|k,v| DEFAULTS.has_key?(k) })
|
109
|
+
end
|
110
|
+
alias to_h to_hash
|
111
|
+
|
112
|
+
# Internal Helpers
|
113
|
+
|
114
|
+
|
115
|
+
def logger
|
116
|
+
init_logging! unless @logger
|
117
|
+
@logger
|
118
|
+
end
|
119
|
+
|
120
|
+
def backend
|
121
|
+
init_backend! unless @backend
|
122
|
+
@backend
|
123
|
+
end
|
124
|
+
|
125
|
+
def backend=(backend)
|
126
|
+
set(:backend, backend)
|
127
|
+
@backend = nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def dev?
|
131
|
+
self[:env] && Array(self[:development_environments]).include?(self[:env])
|
132
|
+
end
|
133
|
+
|
134
|
+
def warn_development?
|
135
|
+
dev? && backend.kind_of?(Backend::Null)
|
136
|
+
end
|
137
|
+
|
138
|
+
def public?
|
139
|
+
return true if self[:report_data]
|
140
|
+
return false if self[:report_data] == false
|
141
|
+
|
142
|
+
!self[:env] || !dev?
|
143
|
+
end
|
144
|
+
|
145
|
+
def debug?
|
146
|
+
!!self[:debug]
|
147
|
+
end
|
148
|
+
|
149
|
+
def log_debug?
|
150
|
+
return debug? if self[:'logging.debug'].nil?
|
151
|
+
|
152
|
+
!!self[:'logging.debug']
|
153
|
+
end
|
154
|
+
|
155
|
+
def ignored_classes
|
156
|
+
ignore_only = get(:'exceptions.ignore_only')
|
157
|
+
return ignore_only if ignore_only
|
158
|
+
return DEFAULTS[:'exceptions.ignore'] unless ignore = get(:'exceptions.ignore')
|
159
|
+
|
160
|
+
DEFAULTS[:'exceptions.ignore'] | Array(ignore)
|
161
|
+
end
|
162
|
+
|
163
|
+
def ca_bundle_path
|
164
|
+
if self[:'connection.system_ssl_cert_chain'] && File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE)
|
165
|
+
OpenSSL::X509::DEFAULT_CERT_FILE
|
166
|
+
elsif self[:'connection.ssl_ca_bundle_path']
|
167
|
+
self[:'connection.ssl_ca_bundle_path']
|
168
|
+
else
|
169
|
+
local_cert_path
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def local_cert_path
|
174
|
+
File.expand_path(File.join('..', '..', '..', 'resources', 'ca-bundle.crt'), __FILE__)
|
175
|
+
end
|
176
|
+
|
177
|
+
def connection_port
|
178
|
+
if self[:'connection.port']
|
179
|
+
self[:'connection.port']
|
180
|
+
elsif self[:'connection.secure']
|
181
|
+
443
|
182
|
+
else
|
183
|
+
80
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def connection_protocol
|
188
|
+
if self[:'connection.secure']
|
189
|
+
'https'
|
190
|
+
else
|
191
|
+
'http'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def max_queue_size
|
196
|
+
self[:max_queue_size]
|
197
|
+
end
|
198
|
+
|
199
|
+
def params_filters
|
200
|
+
Array(self[:'request.filter_keys'])
|
201
|
+
end
|
202
|
+
|
203
|
+
def excluded_request_keys
|
204
|
+
[].tap do |keys|
|
205
|
+
keys << :session if self[:'request.disable_session']
|
206
|
+
keys << :params if self[:'request.disable_params']
|
207
|
+
keys << :cgi_data if self[:'request.disable_environment']
|
208
|
+
keys << :url if self[:'request.disable_url']
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def log_level(key = :'logging.level')
|
213
|
+
case self[key].to_s
|
214
|
+
when /\A(0|debug)\z/i then Logger::DEBUG
|
215
|
+
when /\A(1|info)\z/i then Logger::INFO
|
216
|
+
when /\A(2|warn)\z/i then Logger::WARN
|
217
|
+
when /\A(3|error)\z/i then Logger::ERROR
|
218
|
+
else
|
219
|
+
Logger::INFO
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def load_plugin?(name)
|
224
|
+
return false if includes_token?(self[:'skipped_plugins'], name)
|
225
|
+
return true unless self[:plugins].kind_of?(Array)
|
226
|
+
|
227
|
+
includes_token?(self[:plugins], name)
|
228
|
+
end
|
229
|
+
|
230
|
+
def root_regexp
|
231
|
+
return @root_regexp if @root_regexp
|
232
|
+
return nil if @no_root
|
233
|
+
|
234
|
+
root = get(:root).to_s
|
235
|
+
@no_root = true and return nil unless root =~ NOT_BLANK
|
236
|
+
|
237
|
+
@root_regexp = Regexp.new("^#{ Regexp.escape(root) }")
|
238
|
+
end
|
239
|
+
|
240
|
+
def detected_framework
|
241
|
+
if self[:framework] =~ NOT_BLANK
|
242
|
+
self[:framework].to_sym
|
243
|
+
elsif defined?(::Rails::VERSION) && ::Rails::VERSION::STRING > '3.0'
|
244
|
+
:rails
|
245
|
+
elsif defined?(::Sinatra::VERSION)
|
246
|
+
:sinatra
|
247
|
+
elsif defined?(::Rack.release)
|
248
|
+
:rack
|
249
|
+
else
|
250
|
+
:ruby
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def framework_name
|
255
|
+
case detected_framework
|
256
|
+
when :rails then "Rails #{::Rails::VERSION::STRING}"
|
257
|
+
when :sinatra then "Sinatra #{::Sinatra::VERSION}"
|
258
|
+
when :rack then "Rack #{::Rack.release}"
|
259
|
+
else
|
260
|
+
"Ruby #{RUBY_VERSION}"
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
private
|
265
|
+
|
266
|
+
def detect_revision!
|
267
|
+
return if self[:revision]
|
268
|
+
|
269
|
+
set(:revision, Util::Revision.detect(self[:root]))
|
270
|
+
end
|
271
|
+
|
272
|
+
def log_path
|
273
|
+
return if log_stdout?
|
274
|
+
return if !self[:'logging.path']
|
275
|
+
|
276
|
+
locate_absolute_path(self[:'logging.path'], self[:root])
|
277
|
+
end
|
278
|
+
|
279
|
+
def config_path
|
280
|
+
config_paths.first
|
281
|
+
end
|
282
|
+
|
283
|
+
def config_paths
|
284
|
+
Array(ENV['HONEYBADGER_CONFIG_PATH'] || get(:'config.path')).map do |c|
|
285
|
+
locate_absolute_path(c, self[:root])
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def default_backend
|
290
|
+
return Backend::Server.new(self) if public?
|
291
|
+
|
292
|
+
Backend::Null.new(self)
|
293
|
+
end
|
294
|
+
|
295
|
+
def init_backend!
|
296
|
+
if self[:backend].is_a?(String) || self[:backend].is_a?(Symbol)
|
297
|
+
@backend = Backend.for(self[:backend].to_sym).new(self)
|
298
|
+
return
|
299
|
+
end
|
300
|
+
|
301
|
+
if ruby[:backend].respond_to?(:notify)
|
302
|
+
@backend = ruby[:backend]
|
303
|
+
return
|
304
|
+
end
|
305
|
+
|
306
|
+
if ruby[:backend]
|
307
|
+
logger.warn(sprintf('Unknown backend: %p; default will be used. Backend must respond to #notify', self[:backend]))
|
308
|
+
end
|
309
|
+
|
310
|
+
@backend = default_backend
|
311
|
+
end
|
312
|
+
|
313
|
+
def build_stdout_logger
|
314
|
+
logger = Logger.new($stdout)
|
315
|
+
logger.formatter = lambda do |severity, datetime, progname, msg|
|
316
|
+
"#{msg}\n"
|
317
|
+
end
|
318
|
+
logger.level = log_level
|
319
|
+
Logging::FormattedLogger.new(logger)
|
320
|
+
end
|
321
|
+
|
322
|
+
def build_file_logger(path)
|
323
|
+
Logger.new(path).tap do |logger|
|
324
|
+
logger.level = log_level
|
325
|
+
logger.formatter = Logger::Formatter.new
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def log_stdout?
|
330
|
+
self[:'logging.path'] && self[:'logging.path'].to_s.downcase == 'stdout'
|
331
|
+
end
|
332
|
+
|
333
|
+
def build_logger
|
334
|
+
return ruby[:logger] if ruby[:logger]
|
335
|
+
|
336
|
+
return build_stdout_logger if log_stdout?
|
337
|
+
|
338
|
+
if path = log_path
|
339
|
+
FileUtils.mkdir_p(path.dirname) unless path.dirname.writable?
|
340
|
+
return build_file_logger(path)
|
341
|
+
end
|
342
|
+
|
343
|
+
return framework[:logger] if framework[:logger]
|
344
|
+
|
345
|
+
Logger.new(nil)
|
346
|
+
end
|
347
|
+
|
348
|
+
def init_logging!
|
349
|
+
@logger = Logging::ConfigLogger.new(self, build_logger)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Takes an Array and a value and returns true if the value exists in the
|
353
|
+
# array in String or Symbol form, otherwise false.
|
354
|
+
def includes_token?(obj, value)
|
355
|
+
return false unless obj.kind_of?(Array)
|
356
|
+
|
357
|
+
obj.map(&:to_sym).include?(value.to_sym)
|
358
|
+
end
|
359
|
+
|
360
|
+
def locate_absolute_path(path, root)
|
361
|
+
path = Pathname.new(path.to_s)
|
362
|
+
if path.absolute?
|
363
|
+
path
|
364
|
+
else
|
365
|
+
Pathname.new(root.to_s).join(path.to_s)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def load_config_from_disk
|
370
|
+
if (path = config_paths.find(&:exist?)) && path.file?
|
371
|
+
Yaml.new(path, self[:env]).tap do |yml|
|
372
|
+
yield(yml) if block_given?
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def undotify_keys(hash)
|
378
|
+
{}.tap do |new_hash|
|
379
|
+
hash.each_pair do |k,v|
|
380
|
+
if k.to_s =~ DOTTED_KEY
|
381
|
+
new_hash[$1] ||= {}
|
382
|
+
new_hash[$1] = undotify_keys(new_hash[$1].merge({$2 => v}))
|
383
|
+
else
|
384
|
+
new_hash[k.to_s] = v
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
require 'zlib'
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
require 'datumfactory/version'
|
8
|
+
|
9
|
+
module Datumfactory
|
10
|
+
module Util
|
11
|
+
class HTTP
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
HEADERS = {
|
15
|
+
'Content-type'.freeze => 'application/json'.freeze,
|
16
|
+
'Content-Encoding'.freeze => 'deflate'.freeze,
|
17
|
+
'Accept'.freeze => 'text/json, application/json'.freeze,
|
18
|
+
'User-Agent'.freeze => "HB-Ruby #{VERSION}; #{RUBY_VERSION}; #{RUBY_PLATFORM}".freeze
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
ERRORS = [Timeout::Error,
|
22
|
+
Errno::EINVAL,
|
23
|
+
Errno::ECONNRESET,
|
24
|
+
Errno::ECONNREFUSED,
|
25
|
+
Errno::ENETUNREACH,
|
26
|
+
EOFError,
|
27
|
+
Net::HTTPBadResponse,
|
28
|
+
Net::HTTPHeaderSyntaxError,
|
29
|
+
Net::ProtocolError,
|
30
|
+
OpenSSL::SSL::SSLError,
|
31
|
+
SocketError].freeze
|
32
|
+
|
33
|
+
def initialize(config)
|
34
|
+
@config = config
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(endpoint)
|
38
|
+
response = http_connection.get(endpoint)
|
39
|
+
debug { format('http method=GET path=%s code=%d', endpoint.dump, response.code) }
|
40
|
+
response
|
41
|
+
end
|
42
|
+
|
43
|
+
def post(endpoint, payload, headers = nil)
|
44
|
+
response = http_connection.post(endpoint, compress(payload.to_json), http_headers(headers))
|
45
|
+
debug { format('http method=POST path=%s code=%d', endpoint.dump, response.code) }
|
46
|
+
response
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :config
|
52
|
+
|
53
|
+
def http_connection
|
54
|
+
setup_http_connection
|
55
|
+
end
|
56
|
+
|
57
|
+
def http_headers(headers = nil)
|
58
|
+
{}.tap do |hash|
|
59
|
+
hash.merge!(HEADERS)
|
60
|
+
hash.merge!({ 'X-API-Key' => config[:api_key].to_s })
|
61
|
+
hash.merge!(headers) if headers
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def setup_http_connection
|
66
|
+
http_class = Net::HTTP::Proxy(config[:'connection.proxy_host'], config[:'connection.proxy_port'], config[:'connection.proxy_user'], config[:'connection.proxy_pass'])
|
67
|
+
http = http_class.new(config[:'connection.host'], config.connection_port)
|
68
|
+
|
69
|
+
http.read_timeout = config[:'connection.http_read_timeout']
|
70
|
+
http.open_timeout = config[:'connection.http_open_timeout']
|
71
|
+
|
72
|
+
if config[:'connection.secure']
|
73
|
+
http.use_ssl = true
|
74
|
+
|
75
|
+
http.ca_file = config.ca_bundle_path
|
76
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
77
|
+
else
|
78
|
+
http.use_ssl = false
|
79
|
+
end
|
80
|
+
|
81
|
+
http
|
82
|
+
end
|
83
|
+
|
84
|
+
def compress(string, level = Zlib::DEFAULT_COMPRESSION)
|
85
|
+
Zlib::Deflate.deflate(string, level)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/datumfactory/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datumfactory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Bazinet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -32,6 +32,7 @@ extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- ".gitignore"
|
35
|
+
- ".rubocop.yml"
|
35
36
|
- CODE_OF_CONDUCT.md
|
36
37
|
- Gemfile
|
37
38
|
- Gemfile.lock
|
@@ -40,6 +41,10 @@ files:
|
|
40
41
|
- Rakefile
|
41
42
|
- datumfactory.gemspec
|
42
43
|
- lib/datumfactory.rb
|
44
|
+
- lib/datumfactory/config/defaults.rb
|
45
|
+
- lib/datumfactory/config/yaml.rb
|
46
|
+
- lib/datumfactory/util/config.rb
|
47
|
+
- lib/datumfactory/util/http.rb
|
43
48
|
- lib/datumfactory/version.rb
|
44
49
|
homepage: https://github.com/rbazinet/datumfactory-ruby
|
45
50
|
licenses:
|