sc4ry 0.2.0 → 0.2.1

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.
data/lib/sc4ry/config.rb CHANGED
@@ -1,91 +1,99 @@
1
- # Sc4ry module
1
+ # frozen_string_literal: true
2
+
3
+ # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
- # Sc4ry::Config module
5
- # @note namespace
6
- module Config
7
- # Configuration validator for Sc4ry default and circuits configuration
8
- # @private
9
- class Validator
6
+ # Sc4ry::Config module
7
+ # @note namespace
8
+ module Config
9
+ # Configuration validator for Sc4ry default and circuits configuration
10
+ # @private
11
+ class Validator
12
+ # accessor on Circuit definition given for validation
13
+ attr_reader :input
10
14
 
11
- # accessor on Circuit definition given for validation
12
- attr_reader :input
13
- # accessor on circuit initial definition from default config or given in construction by from keyword
14
- # @note altered by reference to final result mapping with {#validate!}
15
- attr_reader :config
16
-
17
- def result
18
- @config
19
- end
20
-
21
- include Sc4ry::Constants
22
- include Sc4ry::Exceptions
23
- # Validator constructor
24
- # @param [Hash] definition the config hash to merge and validate
25
- # @param [Hash] from config hash merged on origin (default : the Sc4ry base config from Constants )
26
- # @return [Validator] a new instance of Validator
27
- def initialize(definition: , from: DEFAULT_CONFIG)
28
- @config = from
29
- @input = definition
30
- end
31
-
32
- # Validation method, alter by reference the config attribut
33
- # @raise ConfigError if un unknown key is given in definition to merge.
34
- def validate!
35
- unknown_keys = @input.keys.difference @config.keys
36
- raise ConfigError::new("Unknown keys in config set : #{unknown_keys.to_s}") unless unknown_keys.empty?
37
- validate_formats
38
- @config.merge! @input
39
- format_exceptions
40
- end
41
-
42
- private
43
- # Validation private sub method
44
- # @raise ConfigError if proposed values haven't the good format and deeply in array
45
- def validate_formats
46
- @input.each do |spec,value|
47
- raise ConfigError::new("#{spec} value #{DEFAULT_CONFIG_FORMATS[spec][:desc]}") unless DEFAULT_CONFIG_FORMATS[spec][:proc].call(value)
48
- if DEFAULT_CONFIG_FORMATS[spec].include? :list then
49
- value.each do |item|
50
- raise ConfigError::new("#{spec} value must be in #{DEFAULT_CONFIG_FORMATS[spec][:list]}") unless DEFAULT_CONFIG_FORMATS[spec][:list].include? item
51
- end
52
- end
53
- end
54
- end
55
-
56
- # adapter for exception key in config String to Constant Class Name if need
57
- # @note by reference
58
- def format_exceptions
59
- @config[:exceptions].map! {|item| item = (item.class == String)? Object.const_get(item) : item }
60
- end
61
-
62
- end
15
+ # accessor on circuit initial definition from default config or given in construction by from keyword
16
+ # @note altered by reference to final result mapping with {#validate!}
17
+ attr_reader :config
18
+
19
+ def result
20
+ @config
21
+ end
22
+
23
+ include Sc4ry::Constants
24
+ include Sc4ry::Exceptions
25
+ # Validator constructor
26
+ # @param [Hash] definition the config hash to merge and validate
27
+ # @param [Hash] from config hash merged on origin (default : the Sc4ry base config from Constants )
28
+ # @return [Validator] a new instance of Validator
29
+ def initialize(definition:, from: DEFAULT_CONFIG)
30
+ @config = from
31
+ @input = definition
32
+ end
63
33
 
64
- # Config Data mapper for block yielding methods for configuration
65
- # @note work for/with {Sc4ry::Circuits.configure} and {Sc4ry::Circuits.register} when block given
66
- class ConfigMapper
34
+ # Validation method, alter by reference the config attribut
35
+ # @raise ConfigError if un unknown key is given in definition to merge.
36
+ def validate!
37
+ unknown_keys = @input.keys.difference @config.keys
38
+ raise ConfigError, "Unknown keys in config set : #{unknown_keys}" unless unknown_keys.empty?
67
39
 
68
- include Sc4ry::Constants
40
+ validate_formats
41
+ @config.merge! @input
42
+ format_exceptions
43
+ end
69
44
 
70
- # config from given definition passed in constructor
71
- attr_reader :config
72
-
73
- # the mapping constructor from a given definition or the default From Sc4ry config (Constant)
74
- # @param [Hash] definition a config hash
75
- # @note creating dynamically accessors on config record given in definition
76
- def initialize(definition: DEFAULT_CONFIG)
77
- @config = definition
78
- @config.each do |key,value|
79
- self.define_singleton_method "#{key.to_s}=".to_sym do |val|
80
- key = __method__.to_s.chop.to_sym
81
- @config[key]=val
82
- end
83
- self.define_singleton_method key do
84
- return @config[__method__]
85
- end
86
- end
45
+ private
46
+
47
+ # Validation private sub method
48
+ # @raise ConfigError if proposed values haven't the good format and deeply in array
49
+ def validate_formats
50
+ @input.each do |spec, value|
51
+ unless DEFAULT_CONFIG_FORMATS[spec][:proc].call(value)
52
+ raise ConfigError,
53
+ "#{spec} value #{DEFAULT_CONFIG_FORMATS[spec][:desc]}"
54
+ end
55
+
56
+ next unless DEFAULT_CONFIG_FORMATS[spec].include? :list
57
+
58
+ value.each do |item|
59
+ unless DEFAULT_CONFIG_FORMATS[spec][:list].include? item
60
+ raise ConfigError,
61
+ "#{spec} value must be in #{DEFAULT_CONFIG_FORMATS[spec][:list]}"
87
62
  end
63
+ end
88
64
  end
65
+ end
66
+
67
+ # adapter for exception key in config String to Constant Class Name if need
68
+ # @note by reference
69
+ def format_exceptions
70
+ @config[:exceptions].map! { |item| item.instance_of?(String) ? Object.const_get(item) : item }
71
+ end
72
+ end
73
+
74
+ # Config Data mapper for block yielding methods for configuration
75
+ # @note work for/with {Sc4ry::Circuits.configure} and {Sc4ry::Circuits.register} when block given
76
+ class ConfigMapper
77
+ include Sc4ry::Constants
89
78
 
79
+ # config from given definition passed in constructor
80
+ attr_reader :config
81
+
82
+ # the mapping constructor from a given definition or the default From Sc4ry config (Constant)
83
+ # @param [Hash] definition a config hash
84
+ # @note creating dynamically accessors on config record given in definition
85
+ def initialize(definition: DEFAULT_CONFIG)
86
+ @config = definition
87
+ @config.each do |key, _value|
88
+ define_singleton_method "#{key}=".to_sym do |val|
89
+ key = __method__.to_s.chop.to_sym
90
+ @config[key] = val
91
+ end
92
+ define_singleton_method key do
93
+ return @config[__method__]
94
+ end
95
+ end
96
+ end
90
97
  end
91
- end
98
+ end
99
+ end
@@ -1,51 +1,55 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
- # Sc4ry::Constants module
5
- # @note namespace
6
- module Constants
7
-
8
- # notifiers available in Sc4ry natively
9
- CURRENT_NOTIFIERS = [:prometheus, :mattermost]
10
-
11
- # the Sc4ry default config entries and values
12
- DEFAULT_CONFIG = {
13
- :max_failure_count => 5,
14
- :timeout_value => 20,
15
- :timeout => false,
16
- :max_timeout_count => 5,
17
- :max_time => 10,
18
- :max_overtime_count => 3,
19
- :check_delay => 30,
20
- :notifiers => [],
21
- :forward_unknown_exceptions => true,
22
- :raise_on_opening => false,
23
- :exceptions => [StandardError, RuntimeError]
24
- }
6
+ # Sc4ry::Constants module
7
+ # @note namespace
8
+ module Constants
9
+ # notifiers available in Sc4ry natively
10
+ CURRENT_NOTIFIERS = %i[prometheus mattermost]
25
11
 
26
- # Default config supported entries with format and Proc checker for {Sc4ry::Config::Validator}
27
- DEFAULT_CONFIG_FORMATS = {
28
- :max_failure_count => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
29
- :timeout_value => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
30
- :timeout => {:proc => Proc::new {|item| [true,false].include? item}, :desc => "must be a Boolean"},
31
- :max_timeout_count => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
32
- :max_time => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
33
- :max_overtime_count => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
34
- :check_delay => {:proc => Proc::new {|item| item.class == Integer}, :desc => "must be an Integer"},
35
- :notifiers => {
36
- :proc => Proc::new {|item|
37
- item.class == Array and item.select {|val| val.class == Symbol }.size == item.size
38
- },
39
- :desc => "must be an Array of Symbol",
40
- :list => CURRENT_NOTIFIERS},
41
- :forward_unknown_exceptions => {:proc => Proc::new {|item| [true,false].include? item}, :desc => "must be a Boolean"},
42
- :raise_on_opening => {:proc => Proc::new {|item| [true,false].include? item}, :desc => "must be a Boolean"},
43
- :exceptions => {
44
- :proc => Proc::new {|item| item.class == Array and item.select {|val|
45
- [Class,String].include? val.class}.size == item.size
46
- },
47
- :desc => "must be an Array of Exception(Class) or String"}
48
- }
12
+ # the Sc4ry default config entries and values
13
+ DEFAULT_CONFIG = {
14
+ max_failure_count: 5,
15
+ timeout_value: 20,
16
+ timeout: false,
17
+ max_timeout_count: 5,
18
+ max_time: 10,
19
+ max_overtime_count: 3,
20
+ check_delay: 30,
21
+ notifiers: [],
22
+ forward_unknown_exceptions: true,
23
+ raise_on_opening: false,
24
+ exceptions: [StandardError, RuntimeError]
25
+ }
49
26
 
50
- end
51
- end
27
+ # Default config supported entries with format and Proc checker for {Sc4ry::Config::Validator}
28
+ DEFAULT_CONFIG_FORMATS = {
29
+ max_failure_count: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
30
+ timeout_value: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
31
+ timeout: { proc: proc { |item| [true, false].include? item }, desc: 'must be a Boolean' },
32
+ max_timeout_count: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
33
+ max_time: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
34
+ max_overtime_count: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
35
+ check_delay: { proc: proc { |item| item.instance_of?(Integer) }, desc: 'must be an Integer' },
36
+ notifiers: {
37
+ proc: proc do |item|
38
+ item.instance_of?(Array) and item.select { |val| val.instance_of?(Symbol) }.size == item.size
39
+ end,
40
+ desc: 'must be an Array of Symbol',
41
+ list: CURRENT_NOTIFIERS
42
+ },
43
+ forward_unknown_exceptions: { proc: proc { |item| [true, false].include? item }, desc: 'must be a Boolean' },
44
+ raise_on_opening: { proc: proc { |item| [true, false].include? item }, desc: 'must be a Boolean' },
45
+ exceptions: {
46
+ proc: proc do |item|
47
+ item.instance_of?(Array) and item.select do |val|
48
+ [Class, String].include? val.class
49
+ end.size == item.size
50
+ end,
51
+ desc: 'must be an Array of Exception(Class) or String'
52
+ }
53
+ }
54
+ end
55
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # rubygems depends
2
4
  require 'rest-client'
3
5
  require 'prometheus/client'
@@ -6,7 +8,7 @@ require 'redis'
6
8
  require 'version'
7
9
 
8
10
  # Stdlibs depends
9
- require 'logger'
11
+ require 'logger'
10
12
  require 'timeout'
11
13
  require 'forwardable'
12
14
  require 'singleton'
@@ -17,7 +19,6 @@ require 'uri'
17
19
  require 'json'
18
20
  require 'yaml'
19
21
 
20
-
21
22
  # Sc4ry internal depends
22
23
  require_relative 'helpers'
23
24
  require_relative 'exceptions'
@@ -31,4 +32,3 @@ require_relative 'backends/init'
31
32
  require_relative 'store'
32
33
  require_relative 'run_controller'
33
34
  require_relative 'circuits'
34
-
@@ -1,50 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
6
+ # Sc4ry::Exceptions module
7
+ # @note namespace
8
+ module Exceptions
9
+ # Exception use in {Sc4ry::Circuits} when running circuit {Sc4ry::Circuits::run}
10
+ class CircuitBreaked < StandardError
11
+ def initialize(msg = 'Circuit just opened')
12
+ super(msg)
13
+ end
14
+ end
4
15
 
5
- # Sc4ry::Exceptions module
6
- # @note namespace
7
- module Exceptions
8
-
9
- # Exception use in {Sc4ry::Circuits} when running circuit {Sc4ry::Circuits::run}
10
- class CircuitBreaked < StandardError
11
- def initialize(msg="Circuit just opened")
12
- super(msg)
13
- end
14
-
15
- end
16
-
17
- # Generic Exception use in {Sc4ry::Circuits}
18
- class Sc4ryGenericError < StandardError
19
- def initialize(msg="")
20
- super(msg)
21
- end
22
-
23
- end
16
+ # Generic Exception use in {Sc4ry::Circuits}
17
+ class Sc4ryGenericError < StandardError
18
+ def initialize(msg = '')
19
+ super(msg)
20
+ end
21
+ end
24
22
 
25
- # Exception use in {Sc4ry::Store} or/and {Sc4ry::Backend} on data string issues
26
- class Sc4ryBackendError < StandardError
27
- def initialize(msg="")
28
- super(msg)
29
- end
30
-
31
- end
23
+ # Exception use in {Sc4ry::Store} or/and {Sc4ry::Backend} on data string issues
24
+ class Sc4ryBackendError < StandardError
25
+ def initialize(msg = '')
26
+ super(msg)
27
+ end
28
+ end
32
29
 
33
- # Exception use in {Sc4ry::Notifiers} on notification issues
34
- class Sc4ryNotifierError < StandardError
35
- def initialize(msg="")
36
- super(msg)
37
- end
38
-
39
- end
40
-
41
- # Exception use in {Sc4ry::Circuits} on config management issues
42
- class ConfigError < StandardError
43
- def initialize(msg="")
44
- super(msg)
45
- end
46
-
47
- end
30
+ # Exception use in {Sc4ry::Notifiers} on notification issues
31
+ class Sc4ryNotifierError < StandardError
32
+ def initialize(msg = '')
33
+ super(msg)
34
+ end
35
+ end
48
36
 
37
+ # Exception use in {Sc4ry::Circuits} on config management issues
38
+ class ConfigError < StandardError
39
+ def initialize(msg = '')
40
+ super(msg)
41
+ end
49
42
  end
50
- end
43
+ end
44
+ end
@@ -1 +1,3 @@
1
- Dir[File.dirname(__FILE__) + '/*.rb'].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
data/lib/sc4ry/helpers.rb CHANGED
@@ -1,22 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
-
5
- # Sc4ry::Helpers module
6
- # @note namespace
7
- module Helpers
8
-
6
+ # Sc4ry::Helpers module
7
+ # @note namespace
8
+ module Helpers
9
9
  # class method (module) to help logging messages
10
10
  # @param [Symbol] target a specific logger, restored old after
11
11
  # @param [Symbol] level (default :info) a logging level (see Logger Stdlib)
12
12
  # @param [String] message your message
13
13
  # @return [Boolean]
14
- def Helpers.log(target: nil, level: :info, message: )
15
- save = Sc4ry::Loggers.current
14
+ def self.log(message:, target: nil, level: :info)
15
+ save = Sc4ry::Loggers.current
16
16
  Sc4ry::Loggers.current = target if target
17
- Sc4ry::Loggers.get.send level, "Sc4ry : #{message}"
17
+ Sc4ry::Loggers.get.send level, "Sc4ry : #{message}"
18
18
  Sc4ry::Loggers.current = save
19
- return true
19
+ true
20
20
  end
21
21
 
22
22
  # TCP/IP service checker
@@ -25,39 +25,34 @@ module Sc4ry
25
25
  # @option options [String] :host hostname
26
26
  # @option options [String] :port TCP port
27
27
  # @option options [String] :url full URL, priority on :host and :port
28
- def Helpers.verify_service(options ={})
29
- begin
30
- if options[:url] then
31
- uri = URI.parse(options[:url])
32
- host = uri.host
33
- port = uri.port
34
- else
35
- host = options[:host]
36
- port = options[:port]
37
- end
38
- Timeout::timeout(1) do
39
- begin
40
- s = TCPSocket.new(host, port)
41
- s.close
42
- return true
43
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
44
- return false
45
- end
46
- end
47
- rescue Timeout::Error
28
+ def self.verify_service(options = {})
29
+ if options[:url]
30
+ uri = URI.parse(options[:url])
31
+ host = uri.host
32
+ port = uri.port
33
+ else
34
+ host = options[:host]
35
+ port = options[:port]
36
+ end
37
+ Timeout.timeout(1) do
38
+ s = TCPSocket.new(host, port)
39
+ s.close
40
+ return true
41
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
48
42
  return false
49
43
  end
44
+ rescue Timeout::Error
45
+ false
50
46
  end
51
47
 
52
48
  # class method (module) to help send notifiesby Sc4ry::Notifiers
53
49
  # @param [Hash] options a Notifying structure
54
50
  # @return [Boolean]
55
- def Helpers.notify(options = {})
51
+ def self.notify(options = {})
56
52
  Sc4ry::Notifiers.list.each do |record|
57
53
  notifier = Sc4ry::Notifiers.get name: record
58
- notifier[:class].notify(options) if options[:config][:notifiers].include? record
54
+ notifier[:class].notify(options) if options[:config][:notifiers].include? record
59
55
  end
60
56
  end
61
-
62
- end
63
- end
57
+ end
58
+ end
data/lib/sc4ry/logger.rb CHANGED
@@ -1,66 +1,67 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Sc4ry module
2
4
  # @note namespace
3
5
  module Sc4ry
4
-
5
6
  # Sc4ry loggers Factory/provider
6
7
  # @note must be accessed by [Sc4ry::Circuits.loggers]
7
8
  class Loggers
8
-
9
- @@loggers = {:stdout => ::Logger.new(STDOUT)}
9
+ @@loggers = { stdout: ::Logger.new($stdout) }
10
10
  @@current = :stdout
11
-
11
+
12
12
  # give the list of available loggers (initially internal Sc4ry logger )
13
13
  # @return [Array] of [symbol] the list of defined loggers
14
- # @note default :stdout => ::Logger(STDOUT) from Ruby Stdlib
14
+ # @note default :stdout => ::Logger($stdout) from Ruby Stdlib
15
15
  # @example usage
16
16
  # include Sc4ry
17
17
  # Circuits.loggers.list_available.each {|logger| puts logger }
18
- def Loggers.list_available
19
- return @@loggers.keys
18
+ def self.list_available
19
+ @@loggers.keys
20
20
  end
21
-
21
+
22
22
  # return the current logger name (initially :stdtout )
23
23
  # @return [symbol] the name of the logger
24
24
  # @example usage
25
25
  # include Sc4ry
26
26
  # puts Circuits.loggers.current
27
- def Loggers.current
28
- return @@current
27
+ def self.current
28
+ @@current
29
29
  end
30
-
30
+
31
31
  # return the current logger Object (initially internal Sc4ry Stdlib Logger on STDOUT )
32
32
  # @return [symbol] the name of the logger
33
33
  # @example usage
34
34
  # include Sc4ry
35
35
  # Circuits.loggers.get :stdout
36
- def Loggers.get
37
- return @@loggers[@@current]
36
+ def self.get
37
+ @@loggers[@@current]
38
38
  end
39
-
40
- # Set the current logger
39
+
40
+ # Set the current logger
41
41
  # @param [Symbol] sym the name of the logger
42
42
  # @return [symbol] the name of the logger updated
43
43
  # @example usage
44
44
  # include Sc4ry
45
45
  # Circuits.loggers.current = :newlogger
46
- def Loggers.current=(sym)
46
+ def self.current=(sym)
47
47
  raise "Logger not define : #{sym}" unless @@loggers.keys.include? sym
48
+
48
49
  @@current = sym
49
- return @@current
50
+ @@current
50
51
  end
51
-
52
+
52
53
  # register un new logger
53
54
  # @param [Symbol] name the name of the new logger
54
55
  # @param [Object] instance the new logger object
55
56
  # raise Sc4ry::Exceptions::Sc4ryGenericError if name is not a Symbol
56
57
  # @example usage
57
58
  # include Sc4ry
58
- # Circuits.loggers.register name: :newlogger, instance: Logger::new('/path/to/my.log')
59
- def Loggers.register(name: , instance: )
60
- raise Sc4ry::Exceptions::Sc4ryGenericError, "name: keyword must be a Symbol" unless name.class == Symbol
59
+ # Circuits.loggers.register name: :newlogger, instance: Logger::new('/path/to/my.log')
60
+ def self.register(name:, instance:)
61
+ raise Sc4ry::Exceptions::Sc4ryGenericError, 'name: keyword must be a Symbol' unless name.instance_of?(Symbol)
62
+
61
63
  @@loggers[name] = instance
62
- return name
64
+ name
63
65
  end
64
-
65
66
  end
66
67
  end