Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.ctrip.infosec.rule.executor; import com.ctrip.infosec.common.Constants; import com.ctrip.infosec.common.model.RiskFact; import com.ctrip.infosec.configs.Configs; import static com.ctrip.infosec.configs.Configs.match; import com.ctrip.infosec.configs.event.PreRule; import com.ctrip.infosec.configs.event.PreRuleTreeNode; import com.ctrip.infosec.configs.event.RuleType; import com.ctrip.infosec.configs.rule.trace.logger.TraceLogger; import com.ctrip.infosec.configs.rulemonitor.RuleMonitorHelper; import com.ctrip.infosec.configs.rulemonitor.RuleMonitorType; import com.ctrip.infosec.rule.Contexts; import com.ctrip.infosec.rule.ThreadLocalCache; import com.ctrip.infosec.rule.converter.Converter; import com.ctrip.infosec.rule.converter.ConverterLocator; import com.ctrip.infosec.rule.converter.PreActionEnums; import com.ctrip.infosec.rule.engine.StatelessPreRuleEngine; import com.ctrip.infosec.sars.util.Collections3; import com.ctrip.infosec.sars.util.GlobalConfig; import com.ctrip.infosec.sars.util.SpringContextHolder; import com.google.common.collect.Lists; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * * @author zhengby */ @Service public class PreRulesExecutorService { private static final Logger logger = LoggerFactory.getLogger(PreRulesExecutorService.class); @Autowired private ConverterLocator converterLocator; // private int timeout = GlobalConfig.getInteger("PreRules.executor.timeout", 10000); /** * ? */ public RiskFact executePreRules(RiskFact fact, boolean isAsync) { // ?? ThreadLocalCache.clear(); // ? execute(fact, isAsync); return fact; } /** * */ void execute(RiskFact fact, boolean isAsync) { // matchRules // List<PreRule> matchedRules = Configs.matchPreRulesInRules(fact, isAsync); // List<String> ruleNos = Collections3.extractToList(matchedRules, "ruleNo"); // logger.debug(Contexts.getLogPrefix() + "matched pre rules: " + StringUtils.join(ruleNos, ", ")); // TraceLogger.traceLog("? " + ruleNos.size() + " ?? ..."); List<PreRuleTreeNode> matchedPreRuleTreeNodes = Configs.matchPreRuleTree(fact, isAsync); while (!matchedPreRuleTreeNodes.isEmpty()) { List<PreRule> matchedRules = Lists.newArrayList(); List<PreRuleTreeNode> children = Lists.newArrayList(); for (PreRuleTreeNode treeNode : matchedPreRuleTreeNodes) { // Nodes?????? boolean matched = true; if (treeNode.getNodes().isEmpty()) { PreRule preRule = treeNode.getData(); if (preRule.isEnabled()) { matched = match(preRule.getConditions(), preRule.getConditionsLogical(), fact.eventBody); } else { matched = false; } } if (matched) { matchedRules.add(treeNode.getData()); if (treeNode.getNodes() != null && !treeNode.getNodes().isEmpty()) { children.addAll(treeNode.getNodes()); } } } matchedPreRuleTreeNodes = children; TraceLogger.traceLog("?: " + Collections3.extractToList(matchedRules, "ruleNo")); if (isAsync) { executeSerial(fact, matchedRules); } else { executeParallel(fact, matchedRules); } } } /** * */ void executeSerial(RiskFact fact, List<PreRule> matchedRules) { StatelessPreRuleEngine statelessPreRuleEngine = SpringContextHolder.getBean(StatelessPreRuleEngine.class); for (PreRule rule : matchedRules) { // ??? boolean matched = Configs.match(rule.getConditions(), rule.getConditionsLogical(), fact.eventBody); if (!matched) { continue; } RuleMonitorHelper.newTrans(fact, RuleMonitorType.PRE_RULE, rule.getRuleNo()); TraceLogger.beginNestedTrans(fact.eventId); TraceLogger.setNestedLogPrefix("[" + rule.getRuleNo() + "]"); Contexts.setPolicyOrRuleNo(rule.getRuleNo()); long start = System.currentTimeMillis(); // try { if (rule.getRuleType() == RuleType.Visual) { PreActionEnums preAction = PreActionEnums.parse(rule.getPreAction()); if (preAction != null) { Converter converter = converterLocator.getConverter(preAction); converter.convert(preAction, rule.getPreActionFieldMapping(), fact, rule.getPreActionResultWrapper(), true); } } else if (rule.getRuleType() == RuleType.Script) { statelessPreRuleEngine.execute(rule.getRuleNo(), fact); } } catch (Exception ex) { logger.warn(Contexts.getLogPrefix() + "?. preRule: " + rule.getRuleNo() + ", exception: " + ex.getMessage()); TraceLogger.traceLog("[" + rule.getRuleNo() + "] EXCEPTION: " + ex.toString()); } finally { long handlingTime = System.currentTimeMillis() - start; if (handlingTime > 100) { logger.info(Contexts.getLogPrefix() + "preRule: " + rule.getRuleNo() + ", usage: " + handlingTime + "ms"); } TraceLogger.traceLog("[" + rule.getRuleNo() + "] usage: " + handlingTime + "ms"); TraceLogger.commitNestedTrans(); RuleMonitorHelper.commitTrans(fact); Contexts.clearLogPrefix(); } } } /** * */ void executeParallel(final RiskFact fact, List<PreRule> matchedRules) { final StatelessPreRuleEngine statelessPreRuleEngine = SpringContextHolder .getBean(StatelessPreRuleEngine.class); final String _logPrefix = Contexts.getLogPrefix(); final String _traceLoggerParentTransId = TraceLogger.getTransId(); List runs1 = Lists.newArrayList(); for (final PreRule rule : matchedRules) { // ??? boolean matched = Configs.match(rule.getConditions(), rule.getConditionsLogical(), fact.eventBody); if (!matched) { continue; } final String packageName = rule.getRuleNo(); runs1.add(new Callable<Boolean>() { @Override public Boolean call() throws Exception { RuleMonitorHelper.newTrans(fact, RuleMonitorType.PRE_RULE, packageName); TraceLogger.beginTrans(fact.eventId); TraceLogger.setParentTransId(_traceLoggerParentTransId); TraceLogger.setLogPrefix("[" + packageName + "]"); Contexts.setPolicyOrRuleNo(packageName); long start = System.currentTimeMillis(); try { // add current execute ruleNo and logPrefix before execution fact.ext.put(Constants.key_ruleNo, rule.getRuleNo()); fact.ext.put(Constants.key_isAsync, true); if (rule.getRuleType() == RuleType.Script) { statelessPreRuleEngine.execute(packageName, fact); } else if (rule.getRuleType() == RuleType.Visual) { PreActionEnums preAction = PreActionEnums.parse(rule.getPreAction()); if (preAction != null) { Converter converter = converterLocator.getConverter(preAction); converter.convert(preAction, rule.getPreActionFieldMapping(), fact, rule.getPreActionResultWrapper(), false); } } // remove current execute ruleNo when finished execution. fact.ext.remove(Constants.key_ruleNo); fact.ext.remove(Constants.key_isAsync); } catch (Throwable ex) { logger.warn(_logPrefix + "?. preRule: " + packageName + ", exception: " + ex.getMessage()); TraceLogger.traceLog("EXCEPTION: " + ex.toString()); } finally { long handlingTime = System.currentTimeMillis() - start; if (handlingTime > 100) { logger.info(_logPrefix + "preRule: " + packageName + ", usage: " + handlingTime + "ms"); } TraceLogger.traceLog("[" + packageName + "] usage: " + handlingTime + "ms"); TraceLogger.commitTrans(); RuleMonitorHelper.commitTrans2Trunk(fact); Contexts.clearLogPrefix(); } return true; } }); } // run try { if (!runs1.isEmpty()) { List<Future<Boolean>> results = ParallelExecutorHolder.excutor.invokeAll(runs1, timeout, TimeUnit.MILLISECONDS); for (Future f : results) { try { if (!f.isDone()) { f.cancel(true); } } catch (Exception e) { // ignored } } } } catch (Exception ex) { // ignored } } }