svcbase 0.1.16
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 +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +63 -0
- data/.rubocop_todo.yml +7 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +8 -0
- data/Jenkinsfile +137 -0
- data/README.md +61 -0
- data/Rakefile +17 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/config/configs/base.yml +5 -0
- data/config/configs/local.yml +0 -0
- data/lib/svcbase/api/base.rb +73 -0
- data/lib/svcbase/api/etag.rb +11 -0
- data/lib/svcbase/api/requesthelpers.rb +34 -0
- data/lib/svcbase/appversion.rb +15 -0
- data/lib/svcbase/config/config_helper.rb +49 -0
- data/lib/svcbase/config.rb +50 -0
- data/lib/svcbase/corelogger.rb +52 -0
- data/lib/svcbase/dumpstats.rb +27 -0
- data/lib/svcbase/exceptions.rb +170 -0
- data/lib/svcbase/formatter.rb +90 -0
- data/lib/svcbase/ipaddr_helper.rb +34 -0
- data/lib/svcbase/middleware/apilogger.rb +184 -0
- data/lib/svcbase/middleware/dateheader.rb +16 -0
- data/lib/svcbase/middleware/requestid.rb +21 -0
- data/lib/svcbase/random.rb +31 -0
- data/lib/svcbase/server.rb +58 -0
- data/lib/svcbase/stats.rb +85 -0
- data/lib/svcbase/thresholder.rb +124 -0
- data/lib/svcbase/version.rb +5 -0
- data/lib/svcbase/worker.rb +66 -0
- data/lib/svcbase.rb +14 -0
- data/locale/en.yml +28 -0
- data/locale/zz.yml +21 -0
- data/svcbase.gemspec +51 -0
- metadata +305 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
# Thresholder is an object that keeps track of how many calls are made
|
5
|
+
# to it and uses the volume over time to determine whether or not to
|
6
|
+
# run the associated block.
|
7
|
+
#
|
8
|
+
# -- get or create a thresholder named 'foo'
|
9
|
+
# thresholder = Core::Thresholder.instance('foo', count: 60, seconds: 60)
|
10
|
+
#
|
11
|
+
# -- run block only if threshold is exceeded
|
12
|
+
# thresholder.exceeded { |count| puts "i have been called #{count} times" }
|
13
|
+
#
|
14
|
+
# -- run block only if threshold has not been exceeded
|
15
|
+
# thresholder.limit { |count| puts "i have been called #{count} times" }
|
16
|
+
#
|
17
|
+
# -- always run block and include current count
|
18
|
+
# thresholder.run { |count| puts "i have been called #{count} times" }
|
19
|
+
#
|
20
|
+
# -- reset counter
|
21
|
+
# thresholder.reset
|
22
|
+
#
|
23
|
+
class Thresholder
|
24
|
+
@instances = {}
|
25
|
+
@class_mutex = Mutex.new
|
26
|
+
|
27
|
+
# return existing thresholder if it exists, otherwise create one
|
28
|
+
def self.instance(*names, **args)
|
29
|
+
raise ArgumentError, 'no identifiers for threshold instance call' if names.empty?
|
30
|
+
|
31
|
+
obj = @instances.dig(*names, :_instance)
|
32
|
+
return obj if obj
|
33
|
+
|
34
|
+
# create the appropriate instance
|
35
|
+
@class_mutex.synchronize do
|
36
|
+
obj = names.inject(@instances) { |buf, key| buf[key] ||= {} }
|
37
|
+
obj[:_instance] ||= new(*names, **args)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# forget a previously created thresholder
|
42
|
+
def self.forget(*names)
|
43
|
+
raise ArgumentError, 'no identifiers for threshold instance call' if names.empty?
|
44
|
+
|
45
|
+
return unless @instances.dig(*names)
|
46
|
+
@class_mutex.synchronize do
|
47
|
+
if names.length == 1
|
48
|
+
@instances.delete names.last
|
49
|
+
else
|
50
|
+
@instances.dig(*names[0..-2])&.delete(names.last)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# run block if threshold is not exceeded
|
56
|
+
def limit
|
57
|
+
raise 'No block passed to Thresholder#limit' unless block_given?
|
58
|
+
count = update_and_return_count
|
59
|
+
yield(count) if count <= @max_count
|
60
|
+
end
|
61
|
+
|
62
|
+
# run block if threshold is exceeded
|
63
|
+
def exceeded
|
64
|
+
raise 'No block passed to Thresholder#exceeded' unless block_given?
|
65
|
+
count = update_and_return_count
|
66
|
+
yield(count) if count > @max_count
|
67
|
+
end
|
68
|
+
|
69
|
+
# always run block
|
70
|
+
def run
|
71
|
+
raise 'No block passed to Thresholder#run' unless block_given?
|
72
|
+
yield(update_and_return_count)
|
73
|
+
end
|
74
|
+
|
75
|
+
# reset internal counters
|
76
|
+
def reset
|
77
|
+
@instance_mutex.synchronize do
|
78
|
+
@queue = [] # each entry is a tuple [ <time>, <count> ]
|
79
|
+
@count = 0 # current total count
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# forbid direct instantiation
|
84
|
+
private_class_method :new, :allocate
|
85
|
+
|
86
|
+
private def initialize(*names, seconds: nil, count: nil)
|
87
|
+
seconds ||= Config.get_i!(:THRESHOLDER_SECONDS, 60)
|
88
|
+
count ||= Config.get_i!(:THRESHOLDER_COUNT, 60)
|
89
|
+
@names = names
|
90
|
+
@instance_mutex = Mutex.new
|
91
|
+
@max_count = count
|
92
|
+
@max_ds = seconds * 10
|
93
|
+
reset
|
94
|
+
end
|
95
|
+
|
96
|
+
private def remove_stale_entries(cutoff)
|
97
|
+
while !@queue.empty? && @queue.last[0] <= cutoff
|
98
|
+
@count -= @queue.last[1]
|
99
|
+
@queue.pop
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private def update_and_return_count
|
104
|
+
@instance_mutex.synchronize do
|
105
|
+
# compute current time in deci-seconds (10th of a second)
|
106
|
+
now_ds = (Time.now.to_f * 10).to_i
|
107
|
+
|
108
|
+
# reduce @count by popping old entries from @queue and decrementing
|
109
|
+
remove_stale_entries(now_ds - @max_ds)
|
110
|
+
|
111
|
+
# increment @count and update @queue
|
112
|
+
if !@queue.empty? && @queue.first[0] == now_ds
|
113
|
+
@queue.first[1] += 1
|
114
|
+
else
|
115
|
+
@queue.unshift [now_ds, 1]
|
116
|
+
end
|
117
|
+
@count += 1
|
118
|
+
|
119
|
+
# directly return the count to avoid races in calling methods
|
120
|
+
return @count
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Core
|
4
|
+
# common start/stop
|
5
|
+
module Worker
|
6
|
+
private def worker_loop(queue)
|
7
|
+
loop do
|
8
|
+
msg = queue.pop # block until there's a msg
|
9
|
+
do_work unless worker_stopping?
|
10
|
+
if worker_stopping?
|
11
|
+
do_stop if respond_to?(:do_stop, true) # check for private and protected too
|
12
|
+
return
|
13
|
+
end
|
14
|
+
queue.clear # ignore work that came in while we were working
|
15
|
+
rescue StandardError => e
|
16
|
+
log.fatal('worker') { ["Worker #{self.class} raised an uncaught exception", e] }
|
17
|
+
return if msg == :do_stop
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_at_startup
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def worker_start
|
26
|
+
worker_stop
|
27
|
+
|
28
|
+
queue = Queue.new
|
29
|
+
@worker_thread = Thread.new do
|
30
|
+
log.debug "Worker thread started for #{self.class}"
|
31
|
+
worker_loop queue
|
32
|
+
log.debug "Worker thread exited for #{self.class}"
|
33
|
+
end
|
34
|
+
@worker_thread[:queue] = queue
|
35
|
+
|
36
|
+
queue.push :do_work if run_at_startup
|
37
|
+
|
38
|
+
@worker_thread[:timer] = Thread.new do
|
39
|
+
loop do
|
40
|
+
sleep interval_seconds
|
41
|
+
queue.push :do_work
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def worker_stop
|
47
|
+
return unless (w = @worker_thread)
|
48
|
+
@worker_thread = nil
|
49
|
+
w[:timer].kill
|
50
|
+
w[:stopping] = true
|
51
|
+
w[:queue].push :do_stop
|
52
|
+
|
53
|
+
# wait a little bit to see if it shuts down then log
|
54
|
+
log.debug "Worker thread draining for #{self.class} #{w.object_id.to_s(32)}" unless w.join(0.2)
|
55
|
+
|
56
|
+
# wait 15 seconds for worker to finish -- if not, kill it
|
57
|
+
return if w.join(Config.get_f!(:WORKER_SHUTDOWN_GRACE_PERIOD, 15))
|
58
|
+
w.kill
|
59
|
+
log.warn "Worker thread killed for #{self.class} #{w.object_id.to_s(32)}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def worker_stopping?
|
63
|
+
Thread.current[:stopping]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/svcbase.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'svcbase/appversion'
|
4
|
+
require 'svcbase/config'
|
5
|
+
require 'svcbase/corelogger'
|
6
|
+
require 'svcbase/dumpstats'
|
7
|
+
require 'svcbase/exceptions'
|
8
|
+
require 'svcbase/ipaddr_helper'
|
9
|
+
require 'svcbase/random'
|
10
|
+
require 'svcbase/server'
|
11
|
+
require 'svcbase/stats'
|
12
|
+
require 'svcbase/thresholder'
|
13
|
+
require 'svcbase/worker'
|
14
|
+
require 'svcbase/version'
|
data/locale/en.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
en:
|
2
|
+
grape:
|
3
|
+
errors:
|
4
|
+
messages:
|
5
|
+
value_not_allowed: 'value is not allowed'
|
6
|
+
invalid: 'is not valid'
|
7
|
+
|
8
|
+
app:
|
9
|
+
errors:
|
10
|
+
# http rc default messages
|
11
|
+
not_modified: 'not modified' # 304
|
12
|
+
bad_request: 'bad request' # 400
|
13
|
+
unauthorized: 'unauthorized' # 401
|
14
|
+
forbidden: 'forbidden' # 403
|
15
|
+
not_found: '%{msgobj} not found' # 404
|
16
|
+
conflict: 'conflict' # 409
|
17
|
+
gone: 'gone/expired' # 410
|
18
|
+
unsupported_media_type: 'unsupported format' # 415
|
19
|
+
unprocessable: 'unprocessable' # 422
|
20
|
+
too_many_requests: 'too many requests' # 429
|
21
|
+
internal_server_error: 'internal server error' # 500
|
22
|
+
|
23
|
+
invalid: '%{msgobj} is not valid'
|
24
|
+
missing: '%{msgobj} is missing'
|
25
|
+
not_allowed: '%{msgobj} is not allowed'
|
26
|
+
expired: '%{msgobj} is expired'
|
27
|
+
already_processed: '%{msgobj} already processed'
|
28
|
+
not_supported: '%{msgobj} is not supported'
|
data/locale/zz.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
en:
|
2
|
+
grape:
|
3
|
+
errors:
|
4
|
+
messages:
|
5
|
+
value_not_allowed: 'value is not allowed'
|
6
|
+
invalid: 'is not valid'
|
7
|
+
|
8
|
+
app:
|
9
|
+
errors:
|
10
|
+
# http rc default messages
|
11
|
+
not_modified: 'not modified' # 304
|
12
|
+
bad_request: 'bad request' # 400
|
13
|
+
unauthorized: 'unauthorized' # 401
|
14
|
+
forbidden: 'forbidden' # 403
|
15
|
+
not_found: '%{msgobj} not found' # 404
|
16
|
+
too_many_requests: 'too many requests' # 429
|
17
|
+
internal_server_error: 'internal server error' # 500
|
18
|
+
|
19
|
+
invalid: '%{msgobj} is not valid'
|
20
|
+
missing: '%{msgobj} is missing'
|
21
|
+
not_allowed: '%{msgobj} is not allowed'
|
data/svcbase.gemspec
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__) # rubocop:disable Style/ExpandPathArguments
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'svcbase/version'
|
6
|
+
|
7
|
+
# rubocop:disable BlockLength
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'svcbase'
|
10
|
+
spec.version = Svcbase::VERSION
|
11
|
+
spec.authors = ['Joe Nardone']
|
12
|
+
spec.email = ['jnardone@secureauth.com']
|
13
|
+
|
14
|
+
spec.summary = 'Base service code'
|
15
|
+
#spec.homepage = 'http://no'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata['allowed_push_host'] = 'https://artifactory.secureauth.com/artifactory/api/gems/rubygems-local'
|
21
|
+
# else
|
22
|
+
# raise 'RubyGems 2.0 or newer is required to protect against ' \
|
23
|
+
# 'public gem pushes.'
|
24
|
+
# end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = 'exe'
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ['lib']
|
32
|
+
|
33
|
+
spec.add_development_dependency 'bundler'
|
34
|
+
spec.add_development_dependency 'climate_control'
|
35
|
+
spec.add_development_dependency 'rack-test'
|
36
|
+
spec.add_development_dependency 'rake'
|
37
|
+
spec.add_development_dependency 'rspec'
|
38
|
+
spec.add_development_dependency 'rubocop'
|
39
|
+
spec.add_development_dependency 'simplecov'
|
40
|
+
spec.add_development_dependency 'simplecov-rcov'
|
41
|
+
spec.add_development_dependency 'timecop'
|
42
|
+
|
43
|
+
spec.add_runtime_dependency 'activesupport'
|
44
|
+
spec.add_runtime_dependency 'grape'
|
45
|
+
spec.add_runtime_dependency 'http_accept_language'
|
46
|
+
spec.add_runtime_dependency 'i18n'
|
47
|
+
spec.add_runtime_dependency 'rack'
|
48
|
+
spec.add_runtime_dependency 'request_store'
|
49
|
+
spec.add_runtime_dependency 'shortuuid'
|
50
|
+
end
|
51
|
+
# rubocop:enable BlockLength
|
metadata
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: svcbase
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.16
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joe Nardone
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-10-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: climate_control
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-test
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
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: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov-rcov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: timecop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: grape
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: http_accept_language
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: i18n
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rack
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: request_store
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :runtime
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: shortuuid
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :runtime
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
237
|
+
description:
|
238
|
+
email:
|
239
|
+
- jnardone@secureauth.com
|
240
|
+
executables: []
|
241
|
+
extensions: []
|
242
|
+
extra_rdoc_files: []
|
243
|
+
files:
|
244
|
+
- ".gitignore"
|
245
|
+
- ".rspec"
|
246
|
+
- ".rubocop.yml"
|
247
|
+
- ".rubocop_todo.yml"
|
248
|
+
- ".ruby-version"
|
249
|
+
- ".travis.yml"
|
250
|
+
- Gemfile
|
251
|
+
- Jenkinsfile
|
252
|
+
- README.md
|
253
|
+
- Rakefile
|
254
|
+
- bin/console
|
255
|
+
- bin/setup
|
256
|
+
- config/configs/base.yml
|
257
|
+
- config/configs/local.yml
|
258
|
+
- lib/svcbase.rb
|
259
|
+
- lib/svcbase/api/base.rb
|
260
|
+
- lib/svcbase/api/etag.rb
|
261
|
+
- lib/svcbase/api/requesthelpers.rb
|
262
|
+
- lib/svcbase/appversion.rb
|
263
|
+
- lib/svcbase/config.rb
|
264
|
+
- lib/svcbase/config/config_helper.rb
|
265
|
+
- lib/svcbase/corelogger.rb
|
266
|
+
- lib/svcbase/dumpstats.rb
|
267
|
+
- lib/svcbase/exceptions.rb
|
268
|
+
- lib/svcbase/formatter.rb
|
269
|
+
- lib/svcbase/ipaddr_helper.rb
|
270
|
+
- lib/svcbase/middleware/apilogger.rb
|
271
|
+
- lib/svcbase/middleware/dateheader.rb
|
272
|
+
- lib/svcbase/middleware/requestid.rb
|
273
|
+
- lib/svcbase/random.rb
|
274
|
+
- lib/svcbase/server.rb
|
275
|
+
- lib/svcbase/stats.rb
|
276
|
+
- lib/svcbase/thresholder.rb
|
277
|
+
- lib/svcbase/version.rb
|
278
|
+
- lib/svcbase/worker.rb
|
279
|
+
- locale/en.yml
|
280
|
+
- locale/zz.yml
|
281
|
+
- svcbase.gemspec
|
282
|
+
homepage:
|
283
|
+
licenses: []
|
284
|
+
metadata: {}
|
285
|
+
post_install_message:
|
286
|
+
rdoc_options: []
|
287
|
+
require_paths:
|
288
|
+
- lib
|
289
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
290
|
+
requirements:
|
291
|
+
- - ">="
|
292
|
+
- !ruby/object:Gem::Version
|
293
|
+
version: '0'
|
294
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
|
+
requirements:
|
296
|
+
- - ">="
|
297
|
+
- !ruby/object:Gem::Version
|
298
|
+
version: '0'
|
299
|
+
requirements: []
|
300
|
+
rubyforge_project:
|
301
|
+
rubygems_version: 2.7.6
|
302
|
+
signing_key:
|
303
|
+
specification_version: 4
|
304
|
+
summary: Base service code
|
305
|
+
test_files: []
|