sc4ry 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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