class Pechkin::MessageMatcher
Allows to match message configuration against received data.
Data is checked againts either allow or forbid rules. But not both at the same time. Each field can contain list of rules to check. 'allow' list means we need at least one matching rule to allow data processing. And 'forbid' list respectievly means we need at least one matching rule to decline data processing.
Constants
- KEY_ALLOW
- KEY_FORBID
Attributes
Public Class Methods
# File lib/pechkin/message_matcher.rb, line 16 def initialize(logger) @logger = logger end
Public Instance Methods
Checks data object against allow / forbid rule sets in message configuration. If data object matches rules it means we can process this data and send message.
@param message_config [Hash] message description. @param data [Hash] request object that need to be inspected whether we
should process this data or not
@return [Boolean] is data object matches message_config rules or not
# File lib/pechkin/message_matcher.rb, line 28 def matches?(message_config, data) check(message_config) if message_config.key?(KEY_ALLOW) rules = message_config[KEY_ALLOW] rules.any? { |r| check_rule(r, r, data) } elsif message_config.key?(KEY_FORBID) rules = message_config[KEY_FORBID] rules.all? { |r| !check_rule(r, r, data) } else true end end
Private Instance Methods
# File lib/pechkin/message_matcher.rb, line 44 def check(msg) return unless msg.key?(KEY_ALLOW) && msg.key?(KEY_FORBID) raise MessageMatchError, 'Both allow and forbid present in message config' end
# File lib/pechkin/message_matcher.rb, line 80 def check_array_rule(top_rule, array, data) return false unless data.is_a?(Array) # Deep array check needs to be done against all elements so we zip arrays # to pair each rule with data element array.zip(data).all? { |r, d| check_rule(top_rule, r, d) } end
# File lib/pechkin/message_matcher.rb, line 72 def check_hash_rule(top_rule, hash, data) return false unless data.is_a?(Hash) hash.all? do |key, value| data.key?(key) && check_rule(top_rule, value, data[key]) end end
Check rule object against data. Rules are checked recursievly, i.e. we can take one field in rule and check it separately as new rule. If all fields are passed check then whole rule passed.
# File lib/pechkin/message_matcher.rb, line 53 def check_rule(top_rule, sub_rule, data) result = if sub_rule.is_a?(Hash) check_hash_rule(top_rule, sub_rule, data) elsif sub_rule.is_a?(Array) check_array_rule(top_rule, sub_rule, data) elsif sub_rule.is_a?(String) check_string_rule(top_rule, sub_rule, data) else sub_rule.eql?(data) end unless result logger.info "Expected #{sub_rule.to_json} got #{data.to_json} when" \ " checking #{top_rule.to_json}" end result end
# File lib/pechkin/message_matcher.rb, line 88 def check_string_rule(_top_rule, str, data) str.eql? data end