<s> import six <EOL> from jsonpath_rw import parse <EOL> from st2common import log as logging <EOL> import st2common . operators as criteria_operators <EOL> from st2common . constants . rules import TRIGGER_PAYLOAD_PREFIX , RULE_TYPE_BACKSTOP <EOL> from st2common . constants . system import SYSTEM_KV_PREFIX <EOL> from st2common . services . keyvalues import KeyValueLookup <EOL> from st2common . util . templating import render_template_with_system_context <EOL> LOG = logging . getLogger ( '<STR_LIT>' ) <EOL> class RuleFilter ( object ) : <EOL> def __init__ ( self , trigger_instance , trigger , rule , extra_info = False ) : <EOL> """<STR_LIT>""" <EOL> self . trigger_instance = trigger_instance <EOL> self . trigger = trigger <EOL> self . rule = rule <EOL> self . extra_info = extra_info <EOL> self . _base_logger_context = { <EOL> '<STR_LIT>' : self . rule , <EOL> '<STR_LIT>' : self . trigger , <EOL> '<STR_LIT>' : self . trigger_instance <EOL> } <EOL> def filter ( self ) : <EOL> """<STR_LIT>""" <EOL> LOG . info ( '<STR_LIT>' , self . rule . ref , self . trigger [ '<STR_LIT:name>' ] , <EOL> extra = self . _base_logger_context ) <EOL> if not self . rule . enabled : <EOL> if self . extra_info : <EOL> LOG . info ( '<STR_LIT>' , self . rule . ref ) <EOL> return False <EOL> criteria = self . rule . criteria <EOL> is_rule_applicable = True <EOL> if criteria and not self . trigger_instance . payload : <EOL> return False <EOL> payload_lookup = PayloadLookup ( self . trigger_instance . payload ) <EOL> LOG . debug ( '<STR_LIT>' , self . trigger_instance . payload , <EOL> extra = self . _base_logger_context ) <EOL> for criterion_k in criteria . keys ( ) : <EOL> criterion_v = criteria [ criterion_k ] <EOL> is_rule_applicable , payload_value , criterion_pattern = self . _check_criterion ( <EOL> criterion_k , criterion_v , payload_lookup ) <EOL> if not is_rule_applicable : <EOL> if self . extra_info : <EOL> criteria_extra_info = '<STR_LIT:\n>' . join ( [ <EOL> '<STR_LIT>' % criterion_k , <EOL> '<STR_LIT>' % criterion_pattern , <EOL> '<STR_LIT>' % criterion_v [ '<STR_LIT:type>' ] , <EOL> '<STR_LIT>' % payload_value <EOL> ] ) <EOL> LOG . info ( '<STR_LIT>' , self . rule . ref , <EOL> criteria_extra_info , <EOL> extra = self . _base_logger_context ) <EOL> break <EOL> if not is_rule_applicable : <EOL> LOG . debug ( '<STR_LIT>' , self . rule . id , self . trigger [ '<STR_LIT:name>' ] , <EOL> extra = self . _base_logger_context ) <EOL> return is_rule_applicable <EOL> def _check_criterion ( self , criterion_k , criterion_v , payload_lookup ) : <EOL> if '<STR_LIT:type>' not in criterion_v : <EOL> return False <EOL> criteria_operator = criterion_v [ '<STR_LIT:type>' ] <EOL> criteria_pattern = criterion_v . get ( '<STR_LIT>' , None ) <EOL> try : <EOL> criteria_pattern = self . _render_criteria_pattern ( criteria_pattern = criteria_pattern ) <EOL> except Exception : <EOL> LOG . exception ( '<STR_LIT>' % <EOL> ( criteria_pattern , criterion_k ) , extra = self . _base_logger_context ) <EOL> return False <EOL> try : <EOL> matches = payload_lookup . get_value ( criterion_k ) <EOL> if matches : <EOL> payload_value = matches [ <NUM_LIT:0> ] if len ( matches ) > <NUM_LIT:0> else matches <EOL> else : <EOL> payload_value = None <EOL> except : <EOL> LOG . exception ( '<STR_LIT>' , criterion_k , <EOL> extra = self . _base_logger_context ) <EOL> return False <EOL> op_func = criteria_operators . get_operator ( criteria_operator ) <EOL> try : <EOL> result = op_func ( value = payload_value , criteria_pattern = criteria_pattern ) <EOL> except : <EOL> LOG . exception ( '<STR_LIT>' , self . rule , <EOL> extra = self . _base_logger_context ) <EOL> return False <EOL> return result , payload_value , criteria_pattern <EOL> def _render_criteria_pattern ( self , criteria_pattern ) : <EOL> if criteria_pattern is None : <EOL> return None <EOL> if not isinstance ( criteria_pattern , six . string_types ) : <EOL> return criteria_pattern <EOL> criteria_pattern = render_template_with_system_context ( value = criteria_pattern ) <EOL> return criteria_pattern <EOL> class SecondPassRuleFilter ( RuleFilter ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , trigger_instance , trigger , rule , first_pass_matched ) : <EOL> """<STR_LIT>""" <EOL> super ( SecondPassRuleFilter , self ) . __init__ ( trigger_instance , trigger , rule ) <EOL> self . first_pass_matched = first_pass_matched <EOL> def filter ( self ) : <EOL> if self . first_pass_matched and self . _is_backstop_rule ( ) : <EOL> return False <EOL> return super ( SecondPassRuleFilter , self ) . filter ( ) <EOL> def _is_backstop_rule ( self ) : <EOL> return self . rule . type [ '<STR_LIT>' ] == RULE_TYPE_BACKSTOP <EOL> class PayloadLookup ( object ) : <EOL> def __init__ ( self , payload ) : <EOL> self . _context = { <EOL> SYSTEM_KV_PREFIX : KeyValueLookup ( ) , <EOL> TRIGGER_PAYLOAD_PREFIX : payload <EOL> } <EOL> def get_value ( self , lookup_key ) : <EOL> expr = parse ( lookup_key ) <EOL> matches = [ match . value for match in expr . find ( self . _context ) ] <EOL> if not matches : <EOL> return None <EOL> return matches </s>
