mirror of
https://github.com/optim-enterprises-bv/siembol.git
synced 2025-11-02 03:18:09 +00:00
Siembol alerting: adding javadoc comments (#797)
* adding javadoc for alerting core * add alerting compiler docs * minor fixes * fixing javadoc tag * adding alerting-storm and alerting-spark javadoc * minor fixes * fixes based on review
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
package uk.co.gresearch.siembol.alerts.common;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object that collects attributes that can be returned by alerting components
|
||||
*
|
||||
* <p>This bean object collects attributes and it is included in an Alerting result object.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingResult
|
||||
*
|
||||
*/
|
||||
public class AlertingAttributes {
|
||||
private EvaluationResult evaluationResult;
|
||||
private String exception;
|
||||
|
||||
@@ -4,12 +4,33 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An object that evaluates events using its internal state including rules
|
||||
*
|
||||
* <p>This interface has two main implementations for evaluating events using
|
||||
* standard and correlation rules.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see uk.co.gresearch.siembol.alerts.engine.AlertingEngineImpl
|
||||
* @see uk.co.gresearch.siembol.alerts.correlationengine.CorrelationEngineImpl
|
||||
* @see CompositeAlertingEngine
|
||||
*
|
||||
*/
|
||||
|
||||
public interface AlertingEngine {
|
||||
ObjectReader JSON_READER = new ObjectMapper()
|
||||
.readerFor(new TypeReference<Map<String, Object>>() { });
|
||||
|
||||
/**
|
||||
* Evaluates event and returns alerting result with a matching result and additional attributes
|
||||
*
|
||||
* @param event serialized event as json string
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*/
|
||||
default AlertingResult evaluate(String event) {
|
||||
try {
|
||||
Map<String, Object> eventMap = JSON_READER.readValue(event);
|
||||
@@ -19,9 +40,25 @@ public interface AlertingEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates event and returns alerting result with a matching result and additional attributes
|
||||
*
|
||||
* @param event deserialized event as map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*/
|
||||
AlertingResult evaluate(Map<String, Object> event);
|
||||
|
||||
/**
|
||||
* Returns an alerting engine type
|
||||
*
|
||||
* @return alerting engine type
|
||||
* @see AlertingEngineType
|
||||
*/
|
||||
AlertingEngineType getAlertingEngineType();
|
||||
|
||||
/**
|
||||
* Removes unused old internal state.
|
||||
*/
|
||||
default void clean() {}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package uk.co.gresearch.siembol.alerts.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An enum of alerting engine types
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see #SIEMBOL_ALERTS
|
||||
* @see #SIEMBOL_CORRELATION_ALERTS
|
||||
*
|
||||
*/
|
||||
public enum AlertingEngineType implements Serializable {
|
||||
SIEMBOL_ALERTS("siembol_alerts"),
|
||||
SIEMBOL_CORRELATION_ALERTS("siembol_correlation_alerts");
|
||||
|
||||
@@ -2,7 +2,19 @@ package uk.co.gresearch.siembol.alerts.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An enum of fields that can be added into the event after matching the rule
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see #FULL_RULE_NAME
|
||||
* @see #RULE_NAME
|
||||
* @see #MAX_PER_HOUR_FIELD
|
||||
* @see #MAX_PER_DAY_FIELD
|
||||
* @see #EXCEPTION
|
||||
* @see #PROCESSING_TIME
|
||||
* @see #CORRELATED_ALERTS
|
||||
*
|
||||
*/
|
||||
public enum AlertingFields {
|
||||
FULL_RULE_NAME("full_rule_name"),
|
||||
RULE_NAME("rule_name"),
|
||||
|
||||
@@ -3,7 +3,14 @@ package uk.co.gresearch.siembol.alerts.common;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object that combines alerting result status with attributes
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see StatusCode
|
||||
* @see AlertingAttributes
|
||||
*
|
||||
*/
|
||||
public class AlertingResult {
|
||||
public enum StatusCode {
|
||||
OK,
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.common;
|
||||
|
||||
/**
|
||||
* An enum of matching results returned in AlertingResult after engine evaluation of an event.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see #DETECTION_SOURCE_TAG_NAME
|
||||
* @see #DETECTION_SOURCE_TAG_VALUE
|
||||
* @see #CORRELATION_ENGINE_DETECTION_SOURCE_TAG_VALUE
|
||||
* @see #CORRELATION_KEY_TAG_NAME
|
||||
* @see #CORRELATION_ALERT_VISIBLE_TAG_NAME
|
||||
* @see #TAG_TRUE_VALUE
|
||||
*
|
||||
*/
|
||||
public enum AlertingTags {
|
||||
DETECTION_SOURCE_TAG_NAME("detection_source"),
|
||||
DETECTION_SOURCE_TAG_VALUE("siembol_alerts"),
|
||||
|
||||
@@ -5,14 +5,37 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingResult.StatusCode.OK;
|
||||
|
||||
/**
|
||||
* An object that combines of multiple alerting engines of the same type
|
||||
*
|
||||
* <p>This object implements AlertingEngine interface by combining list of AlertingEngine objects.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
* @see uk.co.gresearch.siembol.alerts.correlationengine.CorrelationEngineImpl
|
||||
* @see CompositeAlertingEngine
|
||||
*
|
||||
*/
|
||||
public class CompositeAlertingEngine implements AlertingEngine {
|
||||
private final List<AlertingEngine> alertingEngines;
|
||||
|
||||
/**
|
||||
* Creates the composite alerting engine by using the list of already created alerting engines.
|
||||
*
|
||||
* @param alertingEngines List of underlying alerting engines
|
||||
*/
|
||||
public CompositeAlertingEngine(List<AlertingEngine> alertingEngines) {
|
||||
this.alertingEngines = alertingEngines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates an event by underlying alerting engines and
|
||||
* returns alerting result with a matching result and additional attributes.
|
||||
*
|
||||
* @param event serialized event as json string
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult evaluate(Map<String, Object> event) {
|
||||
List<Map<String, Object>> outputEvents = new ArrayList<>();
|
||||
@@ -39,6 +62,12 @@ public class CompositeAlertingEngine implements AlertingEngine {
|
||||
return new AlertingResult(OK, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an alerting engine type of underlying alerting engines
|
||||
*
|
||||
* @return alerting engine type
|
||||
* @see AlertingEngineType
|
||||
*/
|
||||
@Override
|
||||
public AlertingEngineType getAlertingEngineType() {
|
||||
return alertingEngines.get(0).getAlertingEngineType();
|
||||
|
||||
@@ -1,9 +1,29 @@
|
||||
package uk.co.gresearch.siembol.alerts.common;
|
||||
|
||||
/**
|
||||
* An enum of matching results returned in AlertingResult after engine evaluation of an event.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see #MATCH
|
||||
* @see #NO_MATCH
|
||||
*
|
||||
*/
|
||||
public enum EvaluationResult {
|
||||
/*
|
||||
* The event matched during the evaluation.
|
||||
*/
|
||||
MATCH,
|
||||
/*
|
||||
* The event not matched during the evaluation.
|
||||
*/
|
||||
NO_MATCH;
|
||||
|
||||
/**
|
||||
* Returns negated evaluation result
|
||||
*
|
||||
* @param result evaluation result to be negated
|
||||
* @return negated evaluation result
|
||||
*/
|
||||
public static EvaluationResult negate(EvaluationResult result) {
|
||||
return result == MATCH ? NO_MATCH : MATCH;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,39 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingResult.StatusCode.OK;
|
||||
|
||||
/**
|
||||
* An object that validates, tests and compiles alerting rules
|
||||
*
|
||||
* <p>This interface provides functionality for validating, testing and compiling alerting rules.
|
||||
* Moreover, it computes and provides json schema for alerting rules.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingRulesCompiler
|
||||
* @see AlertingCorrelationRulesCompiler
|
||||
*
|
||||
*/
|
||||
public interface AlertingCompiler {
|
||||
/**
|
||||
* Compiles rules into alerting engine
|
||||
*
|
||||
* @param rules json string with alerting rules
|
||||
* @param logger logger for debugging
|
||||
* @return alerting result with alerting engine
|
||||
* @see AlertingResult
|
||||
* @see AlertingEngine
|
||||
*/
|
||||
AlertingResult compile(String rules, TestingLogger logger);
|
||||
|
||||
/**
|
||||
* Compiles list of rules into alerting engine
|
||||
*
|
||||
* @param rulesList list of json strings with alerting rules
|
||||
* @param logger logger for debugging
|
||||
* @return alerting result with alerting engines
|
||||
* @see AlertingResult
|
||||
* @see AlertingEngine
|
||||
*/
|
||||
default AlertingResult compile(List<String> rulesList, TestingLogger logger) {
|
||||
if (rulesList.size() == 1) {
|
||||
return compile(rulesList.get(0), logger);
|
||||
@@ -37,43 +66,43 @@ public interface AlertingCompiler {
|
||||
return new AlertingResult(OK, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides json schema validator for alerting rules
|
||||
*
|
||||
* @return json schema validator for alerting rules
|
||||
* @see JsonSchemaValidator
|
||||
*
|
||||
*/
|
||||
JsonSchemaValidator getSchemaValidator();
|
||||
|
||||
/**
|
||||
* Wraps an alerting rule into json rules structure
|
||||
*
|
||||
* @param rule json string with alerting rule
|
||||
* @return json string with rules that contain the rule on input
|
||||
* @throws IOException if rule is not valid json alerting rule
|
||||
*
|
||||
*/
|
||||
String wrapRuleToRules(String rule) throws IOException;
|
||||
|
||||
/**
|
||||
* Compiles rules into alerting engine and evaluates an event using the engine
|
||||
*
|
||||
* @param rules json string with alerting rules
|
||||
* @param event json string for evaluation
|
||||
* @return alerting result with testing result
|
||||
* @see AlertingResult
|
||||
*/
|
||||
AlertingResult testRules(String rules, String event);
|
||||
|
||||
default AlertingResult compile(String rules) {
|
||||
return compile(rules, new InactiveTestingLogger());
|
||||
}
|
||||
|
||||
default AlertingResult compile(List<String> rulesList) {
|
||||
return compile(rulesList, new InactiveTestingLogger());
|
||||
}
|
||||
|
||||
default AlertingResult getSchema() {
|
||||
AlertingAttributes attributes = new AlertingAttributes();
|
||||
attributes.setRulesSchema(getSchemaValidator().getJsonSchema().getAttributes().getJsonSchema());
|
||||
return new AlertingResult(OK, attributes);
|
||||
}
|
||||
|
||||
default AlertingResult validateRule(String rule) {
|
||||
try {
|
||||
String rules = wrapRuleToRules(rule);
|
||||
return validateRules(rules);
|
||||
} catch (Exception e) {
|
||||
return AlertingResult.fromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
default AlertingResult validateRules(String rules) {
|
||||
try {
|
||||
return compile(rules);
|
||||
} catch (Exception e) {
|
||||
return AlertingResult.fromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a rule into alerting engine and evaluates an event using the engine
|
||||
*
|
||||
* @param rule json string with an alerting rule
|
||||
* @param event json string for evaluation
|
||||
* @return alerting result with testing result
|
||||
* @see AlertingResult
|
||||
*/
|
||||
default AlertingResult testRule(String rule, String event) {
|
||||
try {
|
||||
String rules = wrapRuleToRules(rule);
|
||||
@@ -83,6 +112,81 @@ public interface AlertingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles rules into alerting engine
|
||||
*
|
||||
* @param rules json string with alerting rules
|
||||
* @return alerting result with alerting engine
|
||||
* @see AlertingResult
|
||||
* @see AlertingEngine
|
||||
*/
|
||||
default AlertingResult compile(String rules) {
|
||||
return compile(rules, new InactiveTestingLogger());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles list of rules into alerting engine
|
||||
*
|
||||
* @param rulesList list of json strings with alerting rules
|
||||
* @return alerting result with alerting engines
|
||||
* @see AlertingResult
|
||||
* @see AlertingEngine
|
||||
*/
|
||||
default AlertingResult compile(List<String> rulesList) {
|
||||
return compile(rulesList, new InactiveTestingLogger());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides json schema for alerting rules
|
||||
*
|
||||
* @return AlertingResult with json schema for alerting rules
|
||||
* @see AlertingResult
|
||||
*
|
||||
*/
|
||||
default AlertingResult getSchema() {
|
||||
AlertingAttributes attributes = new AlertingAttributes();
|
||||
attributes.setRulesSchema(getSchemaValidator().getJsonSchema().getAttributes().getJsonSchema());
|
||||
return new AlertingResult(OK, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates rule by trying to compile them
|
||||
*
|
||||
* @param rule json string with an alerting rule
|
||||
* @return alerting result with status OK if the rule was able to compile
|
||||
* @see AlertingResult
|
||||
*/
|
||||
default AlertingResult validateRule(String rule) {
|
||||
try {
|
||||
String rules = wrapRuleToRules(rule);
|
||||
return validateRules(rules);
|
||||
} catch (Exception e) {
|
||||
return AlertingResult.fromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates rules by trying to compile them
|
||||
*
|
||||
* @param rules json string with alerting rules
|
||||
* @return alerting result with status OK if rules were able to compile
|
||||
* @see AlertingResult
|
||||
*/
|
||||
default AlertingResult validateRules(String rules) {
|
||||
try {
|
||||
return compile(rules);
|
||||
} catch (Exception e) {
|
||||
return AlertingResult.fromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates syntax of rules using json schema validator
|
||||
*
|
||||
* @param rules json string with alerting rules
|
||||
* @return alerting result with status OK if rules have valid syntax
|
||||
* @see AlertingResult
|
||||
*/
|
||||
default AlertingResult validateRulesSyntax(String rules) {
|
||||
try {
|
||||
SiembolResult validationResult = getSchemaValidator().validate(rules);
|
||||
|
||||
@@ -21,6 +21,17 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingResult.StatusCode.OK;
|
||||
/**
|
||||
* An object that validates and compiles correlation alerting rules
|
||||
*
|
||||
* <p>This objects provides functionality for validating and compiling correlation alerting rules.
|
||||
* Moreover, it computes and provides json schema for correlation rules.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingCompiler
|
||||
*
|
||||
*/
|
||||
|
||||
public class AlertingCorrelationRulesCompiler implements AlertingCompiler {
|
||||
private static final ObjectReader JSON_RULES_READER =
|
||||
@@ -38,6 +49,9 @@ public class AlertingCorrelationRulesCompiler implements AlertingCompiler {
|
||||
this.jsonSchemaValidator = jsonSchemaValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult compile(String rules, TestingLogger logger) {
|
||||
AlertingResult validateSchemaResult = validateRulesSyntax(rules);
|
||||
@@ -121,26 +135,48 @@ public class AlertingCorrelationRulesCompiler implements AlertingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JsonSchemaValidator getSchemaValidator() {
|
||||
return jsonSchemaValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not implemented yet
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult testRule(String rule, String event) {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED_YET_MSG);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not implemented yet
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult testRules(String rules, String event) {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED_YET_MSG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating AlertingCorrelationRulesCompiler instance
|
||||
*
|
||||
* @return AlertingCorrelationRulesCompiler instance
|
||||
* @throws Exception if creation of the instance fails
|
||||
*/
|
||||
public static AlertingCompiler createAlertingCorrelationRulesCompiler() throws Exception {
|
||||
JsonSchemaValidator validator = new SiembolJsonSchemaValidator(CorrelationRulesDto.class);
|
||||
return new AlertingCorrelationRulesCompiler(validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String wrapRuleToRules(String ruleStr) throws IOException {
|
||||
CorrelationRuleDto rule = JSON_RULE_READER.readValue(ruleStr);
|
||||
@@ -149,5 +185,4 @@ public class AlertingCorrelationRulesCompiler implements AlertingCompiler {
|
||||
rules.setRules(Arrays.asList(rule));
|
||||
return JSON_RULES_WRITER.writeValueAsString(rules);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,17 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingResult.StatusCode.OK;
|
||||
|
||||
/**
|
||||
* An object that validates, test and compiles standard alerting rules
|
||||
*
|
||||
* <p>This object provides functionality for validating, testing and compiling alerting rules.
|
||||
* Moreover, it computes and provides json schema for alerting rules.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingCompiler
|
||||
*
|
||||
*/
|
||||
public class AlertingRulesCompiler implements AlertingCompiler {
|
||||
private static final ObjectReader JSON_RULES_READER =
|
||||
new ObjectMapper().readerFor(RulesDto.class);
|
||||
@@ -100,6 +110,9 @@ public class AlertingRulesCompiler implements AlertingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult compile(String rules, TestingLogger logger) {
|
||||
AlertingResult validateSchemaResult = validateRulesSyntax(rules);
|
||||
@@ -171,11 +184,17 @@ public class AlertingRulesCompiler implements AlertingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JsonSchemaValidator getSchemaValidator() {
|
||||
return jsonSchemaValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult testRules(String rules, String event) {
|
||||
TestingLogger logger = new StringTestingLogger();
|
||||
@@ -212,6 +231,9 @@ public class AlertingRulesCompiler implements AlertingCompiler {
|
||||
return testResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String wrapRuleToRules(String ruleStr) throws IOException {
|
||||
RuleDto rule = JSON_RULE_READER.readValue(ruleStr);
|
||||
@@ -222,6 +244,12 @@ public class AlertingRulesCompiler implements AlertingCompiler {
|
||||
return JSON_RULES_WRITER.writeValueAsString(rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating AlertingRulesCompiler instance
|
||||
*
|
||||
* @return AlertingRulesCompiler instance
|
||||
* @throws Exception if creation of the instance fails
|
||||
*/
|
||||
public static AlertingCompiler createAlertingRulesCompiler() throws Exception {
|
||||
JsonSchemaValidator validator = new SiembolJsonSchemaValidator(RulesDto.class);
|
||||
return new AlertingRulesCompiler(validator);
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.compiler;
|
||||
|
||||
/**
|
||||
* An enum of matcher types
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see #REGEX_MATCH
|
||||
* @see #IS_IN_SET
|
||||
* @see #CONTAINS
|
||||
* @see #COMPOSITE_OR
|
||||
* @see #COMPOSITE_AND
|
||||
* @see #NUMERIC_COMPARE
|
||||
*
|
||||
*/
|
||||
public enum MatcherType {
|
||||
REGEX_MATCH("REGEX_MATCH"),
|
||||
IS_IN_SET("IS_IN_SET"),
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
package uk.co.gresearch.siembol.alerts.correlationengine;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object that represents an alert context stored in alerting counters
|
||||
*
|
||||
* <p>This object stores the context of the alert used by alerting counters.
|
||||
* It stores timestamp and field values that will be included after triggering the rule.
|
||||
* It implements Comparable interface by comparing timestamps.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertCounter
|
||||
*
|
||||
*/
|
||||
public class AlertContext implements Comparable<AlertContext> {
|
||||
private final long timestamp;
|
||||
private final Object[] fieldsToSend;
|
||||
|
||||
@@ -3,7 +3,18 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* An object that implements alerting counters using heap data structure
|
||||
*
|
||||
* <p>This object implements alerting counters using PriorityQueue of alerting contexts.
|
||||
* It evaluates a new alert and supports cleaning of old alerting contexts.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertContext
|
||||
* @see AlertCounterMetadata
|
||||
*
|
||||
*/
|
||||
public class AlertCounter {
|
||||
private final AlertCounterMetadata counterMetadata;
|
||||
private final PriorityQueue<AlertContext> alertContextHeap = new PriorityQueue<>();
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.correlationengine;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* An object that represents constant alert counter information
|
||||
*
|
||||
* <p>This object stores the constant alert counter metadata.
|
||||
* It is shared between all counters of the same type in order to save the space.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertCounter
|
||||
*
|
||||
*/
|
||||
public class AlertCounterMetadata {
|
||||
public enum Flags {
|
||||
MANDATORY
|
||||
|
||||
@@ -10,7 +10,15 @@ import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingTags.CORRELATION_KEY_TAG_NAME;
|
||||
|
||||
/**
|
||||
* An object that evaluates alerts using correlation rules
|
||||
*
|
||||
* <p>This class implements AlertingEngine interface for evaluating alerts using correlation rules.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
*
|
||||
*/
|
||||
public class CorrelationEngineImpl implements AlertingEngine {
|
||||
private static final String MISSING_CORRELATION_ATTRIBUTES = "Missing fields for alert correlation";
|
||||
private final Map<String, List<CorrelationRule>> alertToCorrelationRulesMap;
|
||||
@@ -18,6 +26,11 @@ public class CorrelationEngineImpl implements AlertingEngine {
|
||||
private final TimeProvider timeProvider;
|
||||
private final List<Pair<String, Object>> outputFields;
|
||||
|
||||
/**
|
||||
* Creates correlation engine using builder pattern.
|
||||
*
|
||||
* @param builder correlation engine builder
|
||||
*/
|
||||
CorrelationEngineImpl(Builder builder) {
|
||||
alertToCorrelationRulesMap = builder.alertToCorrelationRulesMap;
|
||||
correlationRules = builder.correlationRules;
|
||||
@@ -25,6 +38,17 @@ public class CorrelationEngineImpl implements AlertingEngine {
|
||||
this.outputFields = builder.outputFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate alert using correlation rules and returns alerting result with
|
||||
* a matching result and additional attributes such as matching events or exceptions.
|
||||
* It returns matches of all rules.
|
||||
* The rule is correlated based on correlation key field in the alert and
|
||||
* alerting rule name field is used for counting alerts in the rules.
|
||||
*
|
||||
* @param alert deserialized event as map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult evaluate(Map<String, Object> alert) {
|
||||
if (!(alert.get(AlertingFields.RULE_NAME.getAlertingName()) instanceof String)
|
||||
@@ -68,11 +92,17 @@ public class CorrelationEngineImpl implements AlertingEngine {
|
||||
return new AlertingResult(AlertingResult.StatusCode.OK, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingEngineType getAlertingEngineType() {
|
||||
return AlertingEngineType.SIEMBOL_CORRELATION_ALERTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void clean() {
|
||||
long currentTime = timeProvider.getCurrentTimeInMs();
|
||||
@@ -81,6 +111,14 @@ public class CorrelationEngineImpl implements AlertingEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for correlation alerting engine
|
||||
*
|
||||
* <p>This class is using Builder pattern.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static class Builder {
|
||||
private static final String MISSING_ARGUMENTS = "Missing required correlation alerting engine properties";
|
||||
private Map<String, List<CorrelationRule>> alertToCorrelationRulesMap = new HashMap<>();
|
||||
@@ -91,26 +129,57 @@ public class CorrelationEngineImpl implements AlertingEngine {
|
||||
private List<Pair<String, Object>> protections;
|
||||
private List<Pair<String, Object>> outputFields = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Sets time provider for providing the current time
|
||||
*
|
||||
* @param timeProvider time provider
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder timeProvider(TimeProvider timeProvider) {
|
||||
this.timeProvider = timeProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets correlation rules that should be prepared in advance
|
||||
*
|
||||
* @param rules list of correlation alerting rules
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder correlationRules(List<CorrelationRule> rules) {
|
||||
this.correlationRules = rules;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets key-value pairs that will be put into the event after matching a rule
|
||||
*
|
||||
* @param constants list of key-value pairs
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder constants(List<Pair<String, String>> constants) {
|
||||
this.constants = constants;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets key-value pairs with rule protection information
|
||||
* that will be put into the event after matching a rule
|
||||
*
|
||||
* @param protections list of key-value pairs
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder protections(List<Pair<String, Object>> protections) {
|
||||
this.protections = protections;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the correlation alerting engine
|
||||
*
|
||||
* @return correlation engine built from the builder state
|
||||
* @throws IllegalArgumentException in case of wrong arguments
|
||||
*/
|
||||
public AlertingEngine build() {
|
||||
if (correlationRules == null
|
||||
|| correlationRules.isEmpty()
|
||||
|
||||
@@ -11,7 +11,15 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static uk.co.gresearch.siembol.alerts.common.AlertingTags.CORRELATION_KEY_TAG_NAME;
|
||||
|
||||
/**
|
||||
* An object for representing correlation alerting rule
|
||||
*
|
||||
* <p>This derived class of AbstractRule is implementing a correlation alerting rule
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AbstractRule
|
||||
*/
|
||||
public class CorrelationRule extends AbstractRule {
|
||||
public enum Flags {
|
||||
USE_EVENT_TIME,
|
||||
@@ -28,6 +36,11 @@ public class CorrelationRule extends AbstractRule {
|
||||
|
||||
private final List<String> fieldNamesToSend;
|
||||
|
||||
/**
|
||||
* Creates correlation rule using builder pattern.
|
||||
*
|
||||
* @param builder CorrelationRule builder
|
||||
*/
|
||||
protected CorrelationRule(Builder<?> builder) {
|
||||
super(builder);
|
||||
this.alertsThresholds = builder.alertsThresholds;
|
||||
@@ -38,6 +51,21 @@ public class CorrelationRule extends AbstractRule {
|
||||
this.alertToCounterIndex = builder.alertToCounterIndex;
|
||||
this.fieldNamesToSend = builder.fieldNamesToSend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the rule by correlating the alert with other alerts based on the correlation key.
|
||||
* It uses alert counters to count alerts with thresholds specified in the alert counter metadata.
|
||||
* It includes the matching result with attributes in alerting result.
|
||||
* It includes correlated alerts into the attributes after triggering the rule.
|
||||
*
|
||||
*
|
||||
* @param alert map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
* @see AlertCounter
|
||||
* @see AlertCounterMetadata
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult match(Map<String, Object> alert) {
|
||||
String alertName = (String)alert.get(AlertingFields.RULE_NAME.getAlertingName());
|
||||
@@ -70,6 +98,11 @@ public class CorrelationRule extends AbstractRule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unused old internal state in rule counters
|
||||
*
|
||||
* @param currentTime current time in milliseconds
|
||||
*/
|
||||
public void clean(long currentTime) {
|
||||
long waterMark = currentTime - timeWindowInMs - maxLagTimeInMs;
|
||||
alertCounters.keySet().removeIf(x -> cleanAlertCounters(alertCounters.get(x), waterMark));
|
||||
@@ -147,6 +180,14 @@ public class CorrelationRule extends AbstractRule {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a correlation alerting rule
|
||||
*
|
||||
* <p>This abstract class is derived from AbstractRule.Builder class
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends CorrelationRule> extends AbstractRule.Builder<T>{
|
||||
protected static final String ALERT_ALREADY_EXISTS_MSG = "Duplicate alert names for correlation";
|
||||
protected static final String INVALID_ALERT_COUNTER = "Invalid alert counter specification";
|
||||
@@ -165,27 +206,61 @@ public class CorrelationRule extends AbstractRule {
|
||||
protected Map<String, Integer> alertToCounterIndex = new HashMap<>();
|
||||
protected EnumSet<Flags> flags = EnumSet.noneOf(Flags.class);
|
||||
protected List<String> fieldNamesToSend = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Sets the number of alerts that needs to match
|
||||
*
|
||||
* @param alertThresholds threshold for number of alerts to match
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> alertsThresholds(Integer alertThresholds) {
|
||||
this.alertsThresholds = alertThresholds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time sliding window in milliseconds
|
||||
*
|
||||
* @param timeWindowInMs sliding window for evaluation in milliseconds
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> timeWindowInMs(long timeWindowInMs) {
|
||||
this.timeWindowInMs = timeWindowInMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum lag of alerts in milliseconds.
|
||||
* The alerts older than this time can be cleaned and will be not considered during evaluation.
|
||||
*
|
||||
* @param maxLagTimeInSec maximum lag of alerts
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> maxLagTimeInSec(Integer maxLagTimeInSec) {
|
||||
this.maxLagTimeInSec = maxLagTimeInSec;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets correlation rule flags
|
||||
*
|
||||
* @param flags correlation rule flags
|
||||
* @return this builder
|
||||
* @see Flags
|
||||
*/
|
||||
public Builder<T> flags(EnumSet<Flags> flags) {
|
||||
this.flags = flags;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds alert counter into the rule
|
||||
*
|
||||
* @param alertName the name of the alert for correlation
|
||||
* @param threshold threshold of alerts for the counter
|
||||
* @param flags alert counter metadata flags
|
||||
* @return this builder
|
||||
* @see AlertCounterMetadata.Flags
|
||||
*/
|
||||
public Builder<T> addAlertCounter(String alertName, int threshold, EnumSet<AlertCounterMetadata.Flags> flags) {
|
||||
if (threshold <= 0 || threshold > MAX_ALERT_THRESHOLD || alertName == null) {
|
||||
throw new IllegalArgumentException(INVALID_ALERT_COUNTER);
|
||||
@@ -196,12 +271,23 @@ public class CorrelationRule extends AbstractRule {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets alert field names that will be included in the correlated alerts' field after triggering the rule
|
||||
*
|
||||
* @param fieldNames the list of field names
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> fieldNamesToSend(List<String> fieldNames) {
|
||||
this.fieldNamesToSend = fieldNames;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates CorrelationRule builder instance
|
||||
*
|
||||
* @return CorrelationRule builder
|
||||
*/
|
||||
public static CorrelationRule.Builder<CorrelationRule> builder() {
|
||||
|
||||
return new CorrelationRule.Builder<>() {
|
||||
|
||||
@@ -11,7 +11,16 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* An object for alerting rule
|
||||
*
|
||||
* <p>This abstract class is using template pattern for handling common functionality of all alerting rules.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see Rule
|
||||
* @see uk.co.gresearch.siembol.alerts.correlationengine.CorrelationRule
|
||||
*/
|
||||
public abstract class AbstractRule {
|
||||
private final String ruleName;
|
||||
private final String fullRuleName;
|
||||
@@ -20,6 +29,11 @@ public abstract class AbstractRule {
|
||||
private final List<Pair<String, String>> variableOutputFields;
|
||||
|
||||
protected final TestingLogger logger;
|
||||
/**
|
||||
* Creates rule using builder pattern
|
||||
*
|
||||
* @param builder abstract rule builder
|
||||
*/
|
||||
protected AbstractRule(Builder<?> builder) {
|
||||
this.ruleName = builder.ruleName;
|
||||
this.fullRuleName = builder.fullRuleName;
|
||||
@@ -28,14 +42,29 @@ public abstract class AbstractRule {
|
||||
this.logger = builder.logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides rule name
|
||||
*
|
||||
* @return the name of the rule
|
||||
*/
|
||||
public String getRuleName() {
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides full rule name including the rule version
|
||||
*
|
||||
* @return the name of the rule including the version
|
||||
*/
|
||||
public String getFullRuleName() {
|
||||
return fullRuleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts metadata about the rule into the event
|
||||
*
|
||||
* @param event the metadata will be put in the event map
|
||||
*/
|
||||
public void addOutputFieldsToEvent(Map<String, Object> event) {
|
||||
outputFields.forEach(x -> event.put(x.getKey(), x.getValue()));
|
||||
for (Pair<String, String> variableOutputField : variableOutputFields) {
|
||||
@@ -44,8 +73,25 @@ public abstract class AbstractRule {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract AlertingResult match(Map<String, Object> log);
|
||||
/**
|
||||
* Abstract method to be implemented in derived classes.
|
||||
* Evaluates the rule and includes the matching result with attributes in alerting result.
|
||||
*
|
||||
* @param event map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*
|
||||
*/
|
||||
public abstract AlertingResult match(Map<String, Object> event);
|
||||
|
||||
/**
|
||||
* An abstract builder for alerting rules
|
||||
*
|
||||
* <p>This abstract class is using Builder pattern.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends AbstractRule> {
|
||||
private static final String MISSING_ARGUMENTS = "Missing required rule properties";
|
||||
private String ruleName;
|
||||
@@ -59,6 +105,12 @@ public abstract class AbstractRule {
|
||||
|
||||
protected abstract T buildInternally();
|
||||
|
||||
/**
|
||||
* Builds the alerting rule
|
||||
*
|
||||
* @return alerting rule built from the builder state and by calling buildInternally method
|
||||
* @throws IllegalArgumentException in case of wrong arguments
|
||||
*/
|
||||
public T build() {
|
||||
if (ruleName == null
|
||||
|| ruleVersion == null) {
|
||||
@@ -80,30 +132,60 @@ public abstract class AbstractRule {
|
||||
return buildInternally();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name of the rule in builder
|
||||
*
|
||||
* @param name name of the rule
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> name(String name) {
|
||||
this.ruleName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets version of the rule in builder
|
||||
*
|
||||
* @param version version of the rule
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> version(Integer version) {
|
||||
this.ruleVersion = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tags - list of key value pairs
|
||||
*
|
||||
* @param tags list of key value pairs. Values can include variables for substitution.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> tags(List<Pair<String, String>> tags) {
|
||||
this.tags = tags;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the protections - list of key value pairs with maximum allowed matches
|
||||
*
|
||||
* @param protections list of key value pairs for rule protection
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> protections(List<Pair<String, Object>> protections) {
|
||||
this.protections = protections;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the testing logger
|
||||
*
|
||||
* @param logger testing logger with debugging information about matching
|
||||
* @return this builder
|
||||
* @see TestingLogger
|
||||
*/
|
||||
public Builder<T> logger(TestingLogger logger) {
|
||||
this.logger = logger;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,13 +7,26 @@ import uk.co.gresearch.siembol.alerts.common.*;
|
||||
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An object that evaluates events using alerting rules
|
||||
*
|
||||
* <p>This class implements AlertingEngine interface for evaluating events using standard alerting rules.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
*
|
||||
*/
|
||||
public class AlertingEngineImpl implements AlertingEngine {
|
||||
private final String sourceField;
|
||||
private final Map<String, List<Rule>> sourceToRulesTable;
|
||||
private final List<Rule> allSourceRules;
|
||||
private final List<Pair<String, Object>> outputFields;
|
||||
|
||||
/**
|
||||
* Creates Alerting engine using builder pattern.
|
||||
*
|
||||
* @param builder alerting engine builder
|
||||
*/
|
||||
private AlertingEngineImpl(Builder builder) {
|
||||
this.sourceToRulesTable = builder.sourceToRulesTable;
|
||||
this.outputFields = builder.outputFields;
|
||||
@@ -21,6 +34,15 @@ public class AlertingEngineImpl implements AlertingEngine {
|
||||
this.allSourceRules = builder.allSourceRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates event using alerting rules and returns alerting result with
|
||||
* a matching result and additional attributes such as matching events or exceptions.
|
||||
* It returns matches of all rules.
|
||||
*
|
||||
* @param event deserialized event as map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult evaluate(Map<String, Object> event) {
|
||||
if (!(event.get(sourceField) instanceof String)) {
|
||||
@@ -54,6 +76,9 @@ public class AlertingEngineImpl implements AlertingEngine {
|
||||
return new AlertingResult(AlertingResult.StatusCode.OK, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingEngineType getAlertingEngineType() {
|
||||
return AlertingEngineType.SIEMBOL_ALERTS;
|
||||
@@ -88,6 +113,14 @@ public class AlertingEngineImpl implements AlertingEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for alerting engine
|
||||
*
|
||||
* <p>This class is using Builder pattern.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static class Builder {
|
||||
private static final String MISSING_ARGUMENTS = "Missing required alerting engine properties";
|
||||
private String sourceField = SiembolMessageFields.SENSOR_TYPE.toString();
|
||||
@@ -99,31 +132,68 @@ public class AlertingEngineImpl implements AlertingEngine {
|
||||
private List<Pair<String, Object>> protections;
|
||||
private List<Pair<String, Object>> outputFields = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Sets source fields in builder with default value: `source_type`
|
||||
*
|
||||
* @param sourceField name of the field for source type
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder sourceField(String sourceField) {
|
||||
this.sourceField = sourceField;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets wildcard in builder with default value: `*`
|
||||
*
|
||||
* @param wildcardSource string that will match all source types
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder wildcardSource(String wildcardSource) {
|
||||
this.wildcardSource = wildcardSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets alerting rules that should be prepared in advance
|
||||
*
|
||||
* @param rules list of pairs of source type and alerting rule
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder rules(List<Pair<String, Rule>> rules) {
|
||||
this.rules = rules;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets key-value pairs that will be putted into event after matching a rule
|
||||
*
|
||||
* @param constants list of key-value pairs
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder constants(List<Pair<String, String>> constants) {
|
||||
this.constants = constants;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets key-value pairs with rule protection information
|
||||
* that will be putted into event after matching a rule
|
||||
*
|
||||
* @param protections list of key-value pairs
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder protections(List<Pair<String, Object>> protections) {
|
||||
this.protections = protections;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the alerting engine
|
||||
*
|
||||
* @return alerting engine built from the builder state
|
||||
* @throws IllegalArgumentException in case of wrong arguments
|
||||
*/
|
||||
public AlertingEngine build() {
|
||||
if (rules == null
|
||||
|| rules.isEmpty()
|
||||
|
||||
@@ -3,11 +3,30 @@ package uk.co.gresearch.siembol.alerts.engine;
|
||||
import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object for basic matching an event
|
||||
*
|
||||
* <p>This abstract class is using template pattern for handling common functionality of all basic matchers.
|
||||
* The matcher is created for a field.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see Matcher
|
||||
* @see IsInSetMatcher
|
||||
* @see ContainsMatcher
|
||||
* @see RegexMatcher
|
||||
* @see NumericCompareMatcher
|
||||
*/
|
||||
public abstract class BasicMatcher implements Matcher {
|
||||
private final static String MISSING_FIELD_NAME = "Missing field name in a basic matcher";
|
||||
private final String fieldName;
|
||||
private final boolean isNegated;
|
||||
|
||||
/**
|
||||
* Creates basic matcher using builder pattern.
|
||||
*
|
||||
* @param builder Basic matcher builder
|
||||
*/
|
||||
protected BasicMatcher(Builder<?> builder) {
|
||||
if (builder.fieldName == null) {
|
||||
throw new IllegalArgumentException(MISSING_FIELD_NAME);
|
||||
@@ -17,13 +36,21 @@ public abstract class BasicMatcher implements Matcher {
|
||||
this.isNegated = builder.isNegated;
|
||||
}
|
||||
|
||||
public EvaluationResult match(Map<String, Object> log) {
|
||||
if (log.get(fieldName) == null) {
|
||||
/**
|
||||
* Extracts fieldValue from the event and calls matchInternally abstract method.
|
||||
* It negates the result if the matcher is negated.
|
||||
*
|
||||
* @param map map of string to object
|
||||
* @return the evaluation result after evaluation
|
||||
* @see EvaluationResult
|
||||
*/
|
||||
public EvaluationResult match(Map<String, Object> map) {
|
||||
if (map.get(fieldName) == null) {
|
||||
return isNegated ? EvaluationResult.MATCH : EvaluationResult.NO_MATCH;
|
||||
}
|
||||
|
||||
var fieldValue = log.get(fieldName);
|
||||
EvaluationResult result = matchInternally(log, fieldValue);
|
||||
var fieldValue = map.get(fieldName);
|
||||
EvaluationResult result = matchInternally(map, fieldValue);
|
||||
|
||||
if (isNegated) {
|
||||
result = EvaluationResult.negate(result);
|
||||
@@ -32,26 +59,63 @@ public abstract class BasicMatcher implements Matcher {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean canModifyEvent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isNegated() {
|
||||
return isNegated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method to be implemented in derived classes. Evaluates fieldValue internally using event if necessary.
|
||||
* It returns matching statues without considering negated property.
|
||||
*
|
||||
*
|
||||
* @param map event as map of string to object
|
||||
* @param fieldValue value of the field for matching
|
||||
* @return matching result after evaluation
|
||||
*
|
||||
*/
|
||||
protected abstract EvaluationResult matchInternally(Map<String, Object> map, Object fieldValue);
|
||||
|
||||
/**
|
||||
* An abstract builder for basic matchers
|
||||
*
|
||||
* <p>This abstract class is using Builder pattern.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends BasicMatcher> {
|
||||
private String fieldName;
|
||||
private boolean isNegated = false;
|
||||
|
||||
/**
|
||||
* Sets fieldName in builder
|
||||
*
|
||||
* @param name field in which matcher will be registered
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> fieldName(String name) {
|
||||
this.fieldName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets negated in builder
|
||||
*
|
||||
* @param isNegated matcher is negated
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> isNegated(boolean isNegated) {
|
||||
this.isNegated = isNegated;
|
||||
return this;
|
||||
|
||||
@@ -7,33 +7,66 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* An object for matching an event by evaluation of compositions of matchers
|
||||
*
|
||||
* <p>This class is for composing basic and composite matchers.
|
||||
* The matcher is not created for a field and can contain basic matchers registered on different fields.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see Matcher
|
||||
*/
|
||||
public class CompositeMatcher implements Matcher {
|
||||
private final Function<Map<String, Object>, EvaluationResult> evaluationFunction;
|
||||
private final boolean negated;
|
||||
private final boolean canModifyEvent;
|
||||
|
||||
/**
|
||||
* Creates composite matcher using builder pattern.
|
||||
*
|
||||
* @param builder composite matcher builder
|
||||
*/
|
||||
public CompositeMatcher(Builder builder) {
|
||||
this.evaluationFunction = builder.evaluationFunction;
|
||||
this.negated = builder.negated;
|
||||
this.canModifyEvent = builder.canModifyEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the event and returns evaluation result.
|
||||
* The event is evaluated by underlying matchers and combined by logical functions such as AND, OR.
|
||||
*
|
||||
* @param event map of string to object
|
||||
* @return the evaluation result after evaluation
|
||||
* @see EvaluationResult
|
||||
*/
|
||||
@Override
|
||||
public EvaluationResult match(Map<String, Object> log) {
|
||||
EvaluationResult matchersResult = evaluationFunction.apply(log);
|
||||
public EvaluationResult match(Map<String, Object> event) {
|
||||
EvaluationResult matchersResult = evaluationFunction.apply(event);
|
||||
return negated ? EvaluationResult.negate(matchersResult) : matchersResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean canModifyEvent() {
|
||||
return canModifyEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isNegated() {
|
||||
return negated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Composite matcher builder instance.
|
||||
*
|
||||
* @return Contains matcher builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
@@ -57,7 +90,14 @@ public class CompositeMatcher implements Matcher {
|
||||
|
||||
return EvaluationResult.MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for composite matchers
|
||||
*
|
||||
* <p>This class is using Builder pattern.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static class Builder {
|
||||
private static final String EMPTY_MATCHERS = "Empty matchers in the composite matcher";
|
||||
private static final String WRONG_ARGUMENTS = "wrong arguments in the composite matcher";
|
||||
@@ -72,21 +112,46 @@ public class CompositeMatcher implements Matcher {
|
||||
private Function<Map<String, Object>, EvaluationResult> evaluationFunction;
|
||||
private boolean canModifyEvent;
|
||||
|
||||
/**
|
||||
* Sets the matcher type for evaluating the composition
|
||||
*
|
||||
* @param matcherType COMPOSITE_OR or COMPOSITE_AND
|
||||
* @return this builder
|
||||
* @see MatcherType
|
||||
*/
|
||||
public Builder matcherType(MatcherType matcherType) {
|
||||
this.matcherType = matcherType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the matcher is negated
|
||||
*
|
||||
* @param negated the matcher is negated
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder isNegated(boolean negated) {
|
||||
this.negated = negated;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of underlying matchers that should be created in advance
|
||||
*
|
||||
* @param matchers the list of underlying matchers
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder matchers(List<Matcher> matchers) {
|
||||
this.matchers = matchers;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the composite matcher
|
||||
*
|
||||
* @return composite matcher built from the builder state
|
||||
* @throws IllegalArgumentException in case of wrong arguments
|
||||
*/
|
||||
public CompositeMatcher build() {
|
||||
if (matchers == null || matchers.isEmpty()) {
|
||||
throw new IllegalArgumentException(EMPTY_MATCHERS);
|
||||
|
||||
@@ -5,7 +5,17 @@ import uk.co.gresearch.siembol.common.utils.EvaluationLibrary;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* An object for basic matching of substring for an event
|
||||
*
|
||||
* <p>This derived class of BasicMatcher provides functionality for matching a substring.
|
||||
* It supports case-insensitive string comparisons and
|
||||
* substituting variables using current map and string search after the substitution and
|
||||
* specifying matching at start or end of the string.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see BasicMatcher
|
||||
*/
|
||||
public class ContainsMatcher extends BasicMatcher {
|
||||
enum Flags {
|
||||
CONTAINS_VARIABLE,
|
||||
@@ -19,6 +29,11 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
protected final String pattern;
|
||||
protected final BiPredicate<String, String> checkPredicate;
|
||||
|
||||
/**
|
||||
* Creates contains matcher using builder pattern.
|
||||
*
|
||||
* @param builder ContainsMatcher builder
|
||||
*/
|
||||
private ContainsMatcher(ContainsMatcher.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.flags = builder.flags;
|
||||
@@ -26,6 +41,15 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
this.checkPredicate = builder.checkPredicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates fieldValue internally using substring search. It substitutes the variables if needed.
|
||||
* it supports case-insensitive compare if specified and checks for starting or ending requirements if needed.
|
||||
*
|
||||
* @param map event as map of string to object
|
||||
* @param fieldValue value of the field for matching
|
||||
* @return EvaluationResult.MATCH if field value contains the string otherwise EvaluationResult.NO_MATCH
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected EvaluationResult matchInternally(Map<String, Object> map, Object fieldValue) {
|
||||
var fieldStringValue = fieldValue.toString();
|
||||
@@ -49,6 +73,11 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
: EvaluationResult.NO_MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Contains matcher builder instance.
|
||||
*
|
||||
* @return Contains matcher builder
|
||||
*/
|
||||
public static Builder<ContainsMatcher> builder() {
|
||||
|
||||
return new Builder<>() {
|
||||
@@ -72,12 +101,26 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for Contains matchers
|
||||
*
|
||||
* <p>This abstract class is derived from BasicMatcher.Builder class.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends ContainsMatcher>
|
||||
extends BasicMatcher.Builder<T> {
|
||||
protected EnumSet<Flags> flags = EnumSet.noneOf(Flags.class);
|
||||
protected String pattern;
|
||||
protected BiPredicate<String, String> checkPredicate;
|
||||
|
||||
/**
|
||||
* Sets startsWith flag in builder
|
||||
*
|
||||
* @param startsWith matcher is checking whether the substring starts with the string
|
||||
* @return this builder
|
||||
*/
|
||||
public ContainsMatcher.Builder<T> isStartsWith(boolean startsWith) {
|
||||
if (startsWith) {
|
||||
flags.add(Flags.STARTS_WITH);
|
||||
@@ -85,6 +128,12 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets endsWith flag in builder
|
||||
*
|
||||
* @param endsWith matcher is checking whether the substring ends with the string
|
||||
* @return this builder
|
||||
*/
|
||||
public ContainsMatcher.Builder<T> isEndsWith(boolean endsWith) {
|
||||
if (endsWith) {
|
||||
flags.add(Flags.ENDS_WITH);
|
||||
@@ -92,6 +141,12 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets case-insensitive comparing in builder
|
||||
*
|
||||
* @param caseInsensitiveCompare matcher is comparing strings case-insensitively
|
||||
* @return this builder
|
||||
*/
|
||||
public ContainsMatcher.Builder<T> isCaseInsensitiveCompare(boolean caseInsensitiveCompare) {
|
||||
if (caseInsensitiveCompare) {
|
||||
flags.add(Flags.CASE_INSENSITIVE);
|
||||
@@ -99,6 +154,12 @@ public class ContainsMatcher extends BasicMatcher {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets input string to search
|
||||
*
|
||||
* @param data string to search
|
||||
* @return this builder
|
||||
*/
|
||||
public ContainsMatcher.Builder<T> data(String data) {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException(EMPTY_PATTERN_MSG);
|
||||
|
||||
@@ -5,13 +5,27 @@ import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* An object for basic matching of a set of strings for an event
|
||||
*
|
||||
* <p>This derived class of BasicMatcher provides functionality for matching set of strings.
|
||||
* It supports case-insensitive string comparisons and
|
||||
* substituting variables using current map and matching the field after the substitution.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see BasicMatcher
|
||||
*/
|
||||
public class IsInSetMatcher extends BasicMatcher {
|
||||
private final static String EMPTY_SET_OF_STRING = "Empty constantStrings of string in the matcher";
|
||||
private final Set<String> constantStrings;
|
||||
private final List<String> variableStrings;
|
||||
private final boolean caseInsensitiveCompare;
|
||||
|
||||
/**
|
||||
* Creates is in set matcher using builder pattern.
|
||||
*
|
||||
* @param builder IsInSetMatcher builder
|
||||
*/
|
||||
private IsInSetMatcher(Builder<?> builder) {
|
||||
super(builder);
|
||||
this.constantStrings = builder.constantStrings;
|
||||
@@ -19,6 +33,15 @@ public class IsInSetMatcher extends BasicMatcher {
|
||||
this.caseInsensitiveCompare = builder.caseInsensitiveCompare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates fieldValue internally using set of strings. It substitutes the variables if needed.
|
||||
* it supports case-insensitive compare if specified.
|
||||
*
|
||||
* @param map event as map of string to object
|
||||
* @param fieldValue value of the field for matching
|
||||
* @return EvaluationResult.MATCH if one string matches otherwise EvaluationResult.NO_MATCH
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected EvaluationResult matchInternally(Map<String, Object> map, Object fieldValue) {
|
||||
var fieldStringValue = fieldValue.toString();
|
||||
@@ -44,6 +67,11 @@ public class IsInSetMatcher extends BasicMatcher {
|
||||
: EvaluationResult.NO_MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates IsInSet matcher builder instance.
|
||||
*
|
||||
* @return IsInSet matcher builder
|
||||
*/
|
||||
public static Builder<IsInSetMatcher> builder() {
|
||||
|
||||
return new Builder<>() {
|
||||
@@ -67,6 +95,14 @@ public class IsInSetMatcher extends BasicMatcher {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for IsInSet matchers
|
||||
*
|
||||
* <p>This abstract class is derived from BasicMatcher.Builder class.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends IsInSetMatcher>
|
||||
extends BasicMatcher.Builder<T> {
|
||||
private String wordDelimiter = "\n";
|
||||
@@ -75,21 +111,45 @@ public class IsInSetMatcher extends BasicMatcher {
|
||||
protected Set<String> constantStrings;
|
||||
protected List<String> variableStrings;
|
||||
|
||||
/**
|
||||
* Sets wordDelimiter in builder
|
||||
*
|
||||
* @param wordDelimiter is used for splitting words from data string
|
||||
* @return this builder
|
||||
*/
|
||||
public IsInSetMatcher.Builder<T> wordDelimiter(String wordDelimiter) {
|
||||
this.wordDelimiter = wordDelimiter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets case-insensitive comparing in builder
|
||||
*
|
||||
* @param caseInsensitiveCompare matcher is comparing strings case-insensitively
|
||||
* @return this builder
|
||||
*/
|
||||
public IsInSetMatcher.Builder<T> isCaseInsensitiveCompare(boolean caseInsensitiveCompare) {
|
||||
this.caseInsensitiveCompare = caseInsensitiveCompare;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets words as one string in builder
|
||||
*
|
||||
* @param data set of words in one string delimited using word delimiter
|
||||
* @return this builder
|
||||
*/
|
||||
public IsInSetMatcher.Builder<T> data(String data) {
|
||||
String[] words = data.split(wordDelimiter);
|
||||
return words(Arrays.asList(words));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets words as list of strings in builder
|
||||
*
|
||||
* @param words list of words for
|
||||
* @return this builder
|
||||
*/
|
||||
public IsInSetMatcher.Builder<T> words(List<String> words) {
|
||||
this.words = words;
|
||||
return this;
|
||||
|
||||
@@ -4,8 +4,39 @@ import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object for matching an event
|
||||
*
|
||||
* <p>This interface for matching an event and providing metadata for a caller such us
|
||||
* the matcher is negated, or whether it can modify the event.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see uk.co.gresearch.siembol.alerts.engine.AlertingEngineImpl
|
||||
* @see Rule
|
||||
* @see BasicMatcher
|
||||
* @see CompositeMatcher
|
||||
*/
|
||||
public interface Matcher {
|
||||
EvaluationResult match(Map<String, Object> log);
|
||||
/**
|
||||
* Matches the event and returns evaluation result.
|
||||
*
|
||||
* @param event map of string to object
|
||||
* @return the evaluation result after evaluation
|
||||
* @see EvaluationResult
|
||||
*/
|
||||
EvaluationResult match(Map<String, Object> event);
|
||||
/**
|
||||
* Provides information whether the matcher can modify the event and
|
||||
* the caller needs to consider it before matching.
|
||||
*
|
||||
* @return true if the matcher can modify the event, otherwise false
|
||||
*/
|
||||
boolean canModifyEvent();
|
||||
/**
|
||||
* Provides information whether the matcher is negated
|
||||
*
|
||||
* @return true if the matcher is negated, otherwise false
|
||||
*/
|
||||
boolean isNegated();
|
||||
}
|
||||
|
||||
@@ -7,18 +7,43 @@ import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* An object for numeric comparing a field with an expression - a constant or other field in an event
|
||||
*
|
||||
* <p>This derived class of BasicMatcher provides functionality for numeric comparing.
|
||||
* It supports custom comparator and
|
||||
* substituting variables using current map and comparing after the substitution.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see BasicMatcher
|
||||
*/
|
||||
public class NumericCompareMatcher extends BasicMatcher {
|
||||
private static final String MISSING_ARGUMENTS_MSG = "Missing attributes in NumericMatcher";
|
||||
private static final String WRONG_CONSTANT_FORMAT = "Can not convert %s into a number";
|
||||
private final BiPredicate<Double, Double> comparator;
|
||||
private final Function<Map<String, Object>, Optional<Double>> valueSupplier;
|
||||
|
||||
/**
|
||||
* Creates numeric comparison matcher using builder pattern.
|
||||
*
|
||||
* @param builder NumericCompare matcher builder
|
||||
*/
|
||||
private NumericCompareMatcher(NumericCompareMatcher.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.comparator = builder.comparator;
|
||||
this.valueSupplier = builder.valueSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interprets fieldValue as a number and compares it with an expression.
|
||||
* It substitutes the variable in expression if needed.
|
||||
*
|
||||
* @param map event as map of string to object
|
||||
* @param fieldValue value of the field for matching
|
||||
* @return EvaluationResult.MATCH if comparing numeric field with expression returns true,
|
||||
* otherwise EvaluationResult.NO_MATCH
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected EvaluationResult matchInternally(Map<String, Object> map, Object fieldValue) {
|
||||
var doubleFieldValue = getDoubleFromObject(fieldValue);
|
||||
@@ -63,6 +88,11 @@ public class NumericCompareMatcher extends BasicMatcher {
|
||||
return getDoubleFromObject(substituted.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates NumericCompare matcher builder instance.
|
||||
*
|
||||
* @return NumericCompare matcher builder
|
||||
*/
|
||||
public static NumericCompareMatcher.Builder<NumericCompareMatcher> builder() {
|
||||
return new NumericCompareMatcher.Builder<>() {
|
||||
@Override
|
||||
@@ -87,16 +117,36 @@ public class NumericCompareMatcher extends BasicMatcher {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for NumericCompare matchers
|
||||
*
|
||||
* <p>This abstract class is derived from BasicMatcher.Builder class.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends NumericCompareMatcher> extends BasicMatcher.Builder<T> {
|
||||
protected BiPredicate<Double, Double> comparator;
|
||||
protected Function<Map<String, Object>, Optional<Double>> valueSupplier;
|
||||
protected String expression;
|
||||
|
||||
/**
|
||||
* Sets a numeric comparator in builder
|
||||
*
|
||||
* @param comparator numeric comparator bi-predicate that will be used during matching
|
||||
* @return this builder
|
||||
*/
|
||||
public NumericCompareMatcher.Builder<T> comparator(BiPredicate<Double, Double> comparator) {
|
||||
this.comparator = comparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a numeric expression in builder
|
||||
*
|
||||
* @param expression string numeric constant or a variable
|
||||
* @return this builder
|
||||
*/
|
||||
public NumericCompareMatcher.Builder<T> expression(String expression) {
|
||||
this.expression = expression;
|
||||
return this;
|
||||
|
||||
@@ -4,7 +4,15 @@ import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* An object for basic regular matching of an event
|
||||
*
|
||||
* <p>This derived class of BasicMatcher provides functionality for regular expression matching.
|
||||
* It supports extracting fields and put them into an event using regular expression named groups.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see BasicMatcher
|
||||
*/
|
||||
public class RegexMatcher extends BasicMatcher {
|
||||
private static final String EMPTY_PATTERN = "Empty pattern";
|
||||
private static final Pattern VARIABLE_PATTERN =
|
||||
@@ -15,17 +23,36 @@ public class RegexMatcher extends BasicMatcher {
|
||||
private final Pattern pattern;
|
||||
private final List<String> variableNames;
|
||||
|
||||
/**
|
||||
* Creates regex matcher using builder pattern.
|
||||
*
|
||||
* @param builder Regex matcher builder
|
||||
*/
|
||||
private RegexMatcher(Builder<?> builder) {
|
||||
super(builder);
|
||||
this.pattern = builder.pattern;
|
||||
this.variableNames = builder.variableNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides information whether the matcher can modify the event and
|
||||
* the caller needs to consider it before matching.
|
||||
*
|
||||
* @return true if the regex matcher contains variables - named group matching
|
||||
*/
|
||||
@Override
|
||||
public boolean canModifyEvent() {
|
||||
return !variableNames.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates fieldValue internally using pattern. It puts extracted fields if the pattern contains named groups.
|
||||
*
|
||||
* @param map event as map of string to object
|
||||
* @param fieldValue value of the field for matching
|
||||
* @return EvaluationResult.MATCH if pattern matches otherwise EvaluationResult.NO_MATCH
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected EvaluationResult matchInternally(Map<String, Object> map, Object fieldValue) {
|
||||
var fieldStringValue = fieldValue.toString();
|
||||
@@ -42,6 +69,11 @@ public class RegexMatcher extends BasicMatcher {
|
||||
return EvaluationResult.MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates regex matcher builder instance.
|
||||
*
|
||||
* @return regex matcher builder
|
||||
*/
|
||||
public static RegexMatcher.Builder<RegexMatcher> builder() {
|
||||
|
||||
return new RegexMatcher.Builder<>() {
|
||||
@@ -55,11 +87,26 @@ public class RegexMatcher extends BasicMatcher {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for regular expression matchers
|
||||
*
|
||||
* <p>This abstract class is derived from BasicMatcher.Builder class
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends RegexMatcher>
|
||||
extends BasicMatcher.Builder<T> {
|
||||
protected Pattern pattern;
|
||||
protected List<String> variableNames;
|
||||
|
||||
/**
|
||||
* Compiles pattern from string in builder. Renames named groups since regular expression supports
|
||||
* characters: `_`, `:`, which are forbidden in Java patterns
|
||||
*
|
||||
* @param patternStr regular expression specification
|
||||
* @return this builder
|
||||
*/
|
||||
public RegexMatcher.Builder<T> pattern(String patternStr) {
|
||||
//NOTE: java regex does not support : _ in variable names but we want it
|
||||
variableNames = new ArrayList<>();
|
||||
|
||||
@@ -3,7 +3,15 @@ package uk.co.gresearch.siembol.alerts.engine;
|
||||
import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
|
||||
import uk.co.gresearch.siembol.alerts.common.AlertingResult;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An object for alerting rule
|
||||
*
|
||||
* <p>This derived class of AbstractRule is implementing a standard alerting rule
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AbstractRule
|
||||
*/
|
||||
public class Rule extends AbstractRule {
|
||||
public enum RuleFlags {
|
||||
CAN_MODIFY_EVENT,
|
||||
@@ -13,15 +21,30 @@ public class Rule extends AbstractRule {
|
||||
private final List<Matcher> matchers;
|
||||
private final EnumSet<RuleFlags> flags;
|
||||
|
||||
/**
|
||||
* Creates rule using builder pattern.
|
||||
*
|
||||
* @param builder Rule builder
|
||||
*/
|
||||
protected Rule(Builder<?> builder) {
|
||||
super(builder);
|
||||
this.matchers = builder.matchers;
|
||||
this.flags = builder.flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the rule by calling underlying matchers - all matchers are required to match to return MATCH result.
|
||||
* It includes the matching result with attributes in alerting result.
|
||||
* It creates a copy of the event if the rule can modify the event during the evaluation.
|
||||
*
|
||||
* @param event map of string to object
|
||||
* @return alerting result after evaluation
|
||||
* @see AlertingResult
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult match(Map<String, Object> log) {
|
||||
Map<String, Object> current = canModifyEvent() ? new HashMap<>(log) : log;
|
||||
public AlertingResult match(Map<String, Object> event) {
|
||||
Map<String, Object> current = canModifyEvent() ? new HashMap<>(event) : event;
|
||||
for (Matcher matcher : matchers) {
|
||||
EvaluationResult result = matcher.match(current);
|
||||
if (result == EvaluationResult.NO_MATCH) {
|
||||
@@ -37,22 +60,48 @@ public class Rule extends AbstractRule {
|
||||
return AlertingResult.fromEvaluationResult(EvaluationResult.MATCH, current);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides information whether the rule can modify the event during evaluation.
|
||||
* It is used by match method
|
||||
*
|
||||
* @return true if the rule can modify the event otherwise false
|
||||
*/
|
||||
public boolean canModifyEvent() {
|
||||
return flags.contains(RuleFlags.CAN_MODIFY_EVENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for an alerting rule
|
||||
*
|
||||
* <p>This abstract class is derived from AbstractRule.Builder class
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*/
|
||||
public static abstract class Builder<T extends Rule> extends AbstractRule.Builder<T>{
|
||||
protected static final String MISSING_MATCHERS = "Empty matchers in a rule";
|
||||
protected static final String NEGATED_MATCHERS_ONLY = "The rule contains negated matchers only";
|
||||
protected List<Matcher> matchers;
|
||||
protected EnumSet<RuleFlags> flags = EnumSet.noneOf(RuleFlags.class);
|
||||
|
||||
/**
|
||||
* Sets the list of matchers
|
||||
*
|
||||
* @param matchers list of matchers
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> matchers(List<Matcher> matchers) {
|
||||
this.matchers = matchers;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flags of the rule
|
||||
*
|
||||
* @param flags flags of the rule
|
||||
* @return this builder
|
||||
* @see RuleFlags
|
||||
*/
|
||||
public Builder<T> flags(EnumSet<RuleFlags> flags) {
|
||||
this.flags = EnumSet.copyOf(flags);
|
||||
return this;
|
||||
@@ -76,6 +125,11 @@ public class Rule extends AbstractRule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Rule builder instance
|
||||
*
|
||||
* @return Rule builder
|
||||
*/
|
||||
public static Builder<Rule> builder() {
|
||||
|
||||
return new Builder<>() {
|
||||
|
||||
@@ -2,7 +2,17 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing correlation alerts used in correlation attributes
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of a correlation alert and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see CorrelationAttributesDto
|
||||
*/
|
||||
@Attributes(title = "correlation alert", description = "Correlation alert specification")
|
||||
public class CorrelationAlertDto {
|
||||
@JsonProperty("alert")
|
||||
|
||||
@@ -4,7 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing alerting correlation attributes
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of an alerting correlation attributes and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see CorrelationRuleDto
|
||||
*/
|
||||
@Attributes(title = "correlation attributes", description = "Correlation attributes of real-time correlation alert matching")
|
||||
public class CorrelationAttributesDto {
|
||||
@JsonProperty("time_unit")
|
||||
|
||||
@@ -4,7 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing alerting correlation rule
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of an alerting correlation rule and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see CorrelationRulesDto
|
||||
*/
|
||||
@Attributes(title = "correlation rule", description = "Correlation rule for real-time correlation alert matching")
|
||||
public class CorrelationRuleDto {
|
||||
@JsonProperty("rule_name")
|
||||
|
||||
@@ -6,7 +6,16 @@ import uk.co.gresearch.siembol.alerts.common.AlertingTags;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing alerting correlation rules
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of alerting correlation rules and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
*/
|
||||
@Attributes(title = "correlation rules", description = "Correlation rules for real-time correlation alert matching")
|
||||
public class CorrelationRulesDto {
|
||||
public CorrelationRulesDto() {
|
||||
|
||||
@@ -4,7 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing an alerting matcher used in alerting rules
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of an alerting matcher and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see RuleDto
|
||||
*/
|
||||
@Attributes(title = "matcher", description = "Matcher for matching fields")
|
||||
public class MatcherDto {
|
||||
@Attributes(description = "The matcher is enabled", required = false)
|
||||
|
||||
@@ -2,7 +2,21 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* An enum for representing a matcher type used in alerting rules
|
||||
*
|
||||
* <p>This enum is used for json (de)serialisation of matcher type.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see MatcherDto
|
||||
* @see #REGEX_MATCH
|
||||
* @see #IS_IN_SET
|
||||
* @see #CONTAINS
|
||||
* @see #COMPOSITE_AND
|
||||
* @see #COMPOSITE_OR
|
||||
* @see #NUMERIC_COMPARE
|
||||
*/
|
||||
@Attributes(title = "time computation type", description = "Type of time computation")
|
||||
public enum MatcherTypeDto {
|
||||
@JsonProperty("REGEX_MATCH") REGEX_MATCH("REGEX_MATCH"),
|
||||
|
||||
@@ -2,9 +2,19 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
import uk.co.gresearch.siembol.alerts.common.AlertingResult;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* An enum for representing a comparing type used in numeric matcher
|
||||
*
|
||||
* <p>This enum is used for json (de)serialisation of comparing type and providing a comparator for the type.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see MatcherDto
|
||||
*
|
||||
*/
|
||||
@Attributes(title = "numeric compare type", description = "Type of numeric comparison")
|
||||
public enum NumericCompareTypeDto {
|
||||
@JsonProperty("equal")
|
||||
@@ -30,6 +40,11 @@ public enum NumericCompareTypeDto {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the comparator predicate for the numeric compare type.
|
||||
*
|
||||
* @return the comparator for the compare type
|
||||
*/
|
||||
public BiPredicate<Double, Double> getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,17 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing alerting rule
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of an alerting rule and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see RulesDto
|
||||
*/
|
||||
@Attributes(title = "rule", description = "Rule for real-time alert matching")
|
||||
public class RuleDto {
|
||||
@JsonProperty("rule_name")
|
||||
|
||||
@@ -2,7 +2,18 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing a rule protection specification used in alerting rules
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of a rule protection specification and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see RuleDto
|
||||
* @see CorrelationRuleDto
|
||||
*/
|
||||
@Attributes(title = "rule protection", description = "Thresholds for deactivating the rule")
|
||||
public class RuleProtectionDto {
|
||||
@JsonProperty("max_per_hour")
|
||||
|
||||
@@ -6,7 +6,16 @@ import uk.co.gresearch.siembol.alerts.common.AlertingTags;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing alerting rules
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of alerting rules and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
*/
|
||||
@Attributes(title = "rules", description = "Rules for real-time alert matching")
|
||||
public class RulesDto {
|
||||
public RulesDto() {
|
||||
|
||||
@@ -2,7 +2,18 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* A data transfer object for representing a tag used in alerting rules
|
||||
*
|
||||
* <p>This class is used for json (de)serialisation of a tag and
|
||||
* for generating json schema from this class using annotations.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.github.reinert.jjschema.Attributes
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see RuleDto
|
||||
* @see CorrelationRuleDto
|
||||
*/
|
||||
@Attributes(title = "tag", description = "The tag pair added to the event after matching")
|
||||
public class TagDto {
|
||||
@JsonProperty("tag_name")
|
||||
|
||||
@@ -2,7 +2,17 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* An enum for representing a time computation type used in correlation attributes
|
||||
*
|
||||
* <p>This enum is used for json (de)serialisation of time computation type.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see CorrelationAttributesDto
|
||||
* @see #EVENT_TIME
|
||||
* @see #PROCESSING_TIME
|
||||
*/
|
||||
@Attributes(title = "time computation type", description = "Type of time computation")
|
||||
public enum TimeComputationTypeDto {
|
||||
@JsonProperty("event_time") EVENT_TIME("event_time"),
|
||||
|
||||
@@ -2,7 +2,18 @@ package uk.co.gresearch.siembol.alerts.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.github.reinert.jjschema.Attributes;
|
||||
|
||||
/**
|
||||
* An enum for representing a time unit type used in correlation attributes
|
||||
*
|
||||
* <p>This enum is used for json (de)serialisation of time unit type.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see com.fasterxml.jackson.annotation.JsonProperty
|
||||
* @see CorrelationAttributesDto
|
||||
* @see #MINUTES
|
||||
* @see #HOURS
|
||||
* @see #SECONDS
|
||||
*/
|
||||
@Attributes(title = "time unit type", description = "Time unit type for sliding window alert counting")
|
||||
public enum TimeUnitTypeDto {
|
||||
@JsonProperty("minutes") MINUTES("minutes", 60 * 1000L),
|
||||
|
||||
@@ -2,7 +2,32 @@ package uk.co.gresearch.siembol.alerts.protection;
|
||||
|
||||
import uk.co.gresearch.siembol.alerts.common.AlertingResult;
|
||||
|
||||
/**
|
||||
* An object for counting rule matches
|
||||
*
|
||||
* <p>This interface is used for counting rule matches and
|
||||
* providing hourly and daily matches of a rule.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see RuleProtectionSystemImpl
|
||||
*
|
||||
*/
|
||||
public interface RuleProtectionSystem {
|
||||
/**
|
||||
* Increments rule matches and returns hourly and daily matches
|
||||
*
|
||||
* @param fullRuleName full rule name
|
||||
* @return alerting result with hourly and daily matches of the rule after incrementing
|
||||
* @see AlertingResult
|
||||
*/
|
||||
AlertingResult incrementRuleMatches(String fullRuleName);
|
||||
|
||||
/**
|
||||
* Returns hourly and daily matches
|
||||
*
|
||||
* @param fullRuleName full rule name
|
||||
* @return alerting result with hourly and daily matches of the rule
|
||||
* @see AlertingResult
|
||||
*/
|
||||
AlertingResult getRuleMatches(String fullRuleName);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,24 @@ import uk.co.gresearch.siembol.alerts.common.AlertingResult;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* An object for counting rule matches using simple in memory counter
|
||||
*
|
||||
* <p>This class implements RuleProtectionSystem interface using simple in-memory counting.
|
||||
*
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see RuleProtectionSystem
|
||||
* @see SimpleCounter
|
||||
*
|
||||
*/
|
||||
public class RuleProtectionSystemImpl implements RuleProtectionSystem {
|
||||
private static final String UNKNOWN_RULE = "No matches of the rule %s";
|
||||
private final Map<String, SimpleCounter> ruleCounters = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult incrementRuleMatches(String fullRuleName) {
|
||||
if (!ruleCounters.containsKey(fullRuleName)) {
|
||||
@@ -26,6 +38,9 @@ public class RuleProtectionSystemImpl implements RuleProtectionSystem {
|
||||
return new AlertingResult(AlertingResult.StatusCode.OK, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AlertingResult getRuleMatches(String fullRuleName) {
|
||||
if (!ruleCounters.containsKey(fullRuleName)) {
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
package uk.co.gresearch.siembol.alerts.protection;
|
||||
|
||||
import uk.co.gresearch.siembol.common.utils.TimeProvider;
|
||||
|
||||
/**
|
||||
* An object that counts hourly and daily matches
|
||||
*
|
||||
* <p>This object counts hourly and daily matches using simple counting and
|
||||
* current time provided by TimeProvider.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*
|
||||
*/
|
||||
public class SimpleCounter {
|
||||
private final TimeProvider timeProvider;
|
||||
private int lastDay = -1;
|
||||
|
||||
@@ -5,7 +5,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import uk.co.gresearch.siembol.common.model.testing.AlertingSparkArgumentDto;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* A main class of alerting spark application
|
||||
*
|
||||
* <p>This class provides the main function that is executed during submission of a spark job.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*
|
||||
*/
|
||||
public class AlertingSpark {
|
||||
private static final String APP_NAME = "SiembolAlertingSpark";
|
||||
private static final String MISSING_ATTRIBUTES = "Missing testing attributes";
|
||||
|
||||
@@ -2,12 +2,24 @@ package uk.co.gresearch.siembol.spark;
|
||||
|
||||
import uk.co.gresearch.siembol.alerts.common.AlertingEngine;
|
||||
import uk.co.gresearch.siembol.alerts.compiler.AlertingRulesCompiler;
|
||||
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An object for integration of an alerting engine into a spark application
|
||||
*
|
||||
* <p>This class implements Serializable interface.
|
||||
* It serializes engine using alerting rules json string.
|
||||
* It provides functionality for evaluating an event using the alerting engine.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
* @see AlertingSparkResult
|
||||
*
|
||||
*/
|
||||
public class AlertingSparkEngine implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String ALERTING_RULE_COMPILATION_ERROR = "Exception during compiling alerting rules";
|
||||
|
||||
@@ -6,7 +6,21 @@ import org.apache.spark.api.java.JavaSparkContext;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* An object for a spark job that evaluates events using an alerting spark engine
|
||||
*
|
||||
* <p>This class implements Serializable interface.
|
||||
* It uses initialised AlertingSparkEngine instance to evaluate
|
||||
* resilient distributed dataset (RDD) of json strings of events using the MapReduce technique.
|
||||
* AlertingSparkEngine, RDD of events and a Spark context are provided by the builder in the constructor.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingSparkEngine
|
||||
* @see JavaRDD
|
||||
* @see Builder
|
||||
* @see AlertingSparkResult
|
||||
*
|
||||
*/
|
||||
public class AlertingSparkJob implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final JavaRDD<String> rdd;
|
||||
@@ -27,6 +41,19 @@ public class AlertingSparkJob implements Serializable {
|
||||
.fold(AlertingSparkResult.emptyResult(maxResult), AlertingSparkResult::merge);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object for construction AlertingSparkJob instance
|
||||
*
|
||||
* <p>This class uses Builder pattern.
|
||||
* It initialises AlertingSparkEngine from rules, RDD of events from files paths and a Spark context.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingSparkEngine
|
||||
* @see JavaRDD
|
||||
* @see AlertingSparkJob
|
||||
* @see JavaSparkContext
|
||||
*
|
||||
*/
|
||||
public static class Builder {
|
||||
private static final String MISSING_ARGUMENTS_MSG = "Missing arguments for alerts spark job";
|
||||
private static final String EMPTY_FILES_PATHS_MSG = "Files paths are empty";
|
||||
|
||||
@@ -11,7 +11,17 @@ import uk.co.gresearch.siembol.common.model.testing.AlertingSparkTestingResultDt
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object for representing alerting spark result
|
||||
*
|
||||
* <p>This class implements Serializable interface. It contains a list of matched events (json strings) and
|
||||
* the list of exceptions (json strings of ErrorMessages).
|
||||
* It provides functionality for merging two alerting results that is used in the map reduce job.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingSparkTestingResultDto
|
||||
*
|
||||
*/
|
||||
public class AlertingSparkResult implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -34,7 +34,18 @@ import uk.co.gresearch.siembol.common.model.AlertingStormAttributesDto;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* An object for integration of an alerting engine into a storm bolt
|
||||
*
|
||||
* <p>This class extends a Storm BaseRichBolt class to implement a Storm bolt, that
|
||||
* evaluates events using an engine initialised from the rules cached in the ZooKeeper,
|
||||
* watches for the rules update in ZooKeeper and updates the rules without need to restart the topology or the bolt,
|
||||
* emits alerts and exceptions after matching.
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
* @see ZooKeeperConnector
|
||||
*
|
||||
*/
|
||||
public class AlertingEngineBolt extends BaseRichBolt {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String EXCEPTION_MSG_FORMAT = "Alerting Engine exception: %s during evaluating event: %s";
|
||||
|
||||
@@ -18,7 +18,21 @@ import uk.co.gresearch.siembol.common.model.AlertingStormAttributesDto;
|
||||
import uk.co.gresearch.siembol.common.storm.KafkaWriterAnchor;
|
||||
import uk.co.gresearch.siembol.common.storm.KafkaWriterBoltBase;
|
||||
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessage;
|
||||
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
|
||||
|
||||
/**
|
||||
* An object for evaluating alerting protection matches and writing alerts to a kafka topic
|
||||
*
|
||||
* <p>This class extends a Storm BaseRichBolt class in order to implement a Storm bolt, that
|
||||
* evaluates events using an engine initialised from the rules cached in the ZooKeeper,
|
||||
* watches for the rules update in ZooKeeper and updates the rules without need to restart the topology or the bolt and
|
||||
* emits alerts and exceptions after matching.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see KafkaWriterBoltBase
|
||||
* @see ZooKeeperConnector
|
||||
*
|
||||
*/
|
||||
public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
@@ -26,7 +26,17 @@ import java.util.Base64;
|
||||
|
||||
import static org.apache.kafka.clients.consumer.ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG;
|
||||
import static org.apache.kafka.clients.consumer.ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG;
|
||||
|
||||
/**
|
||||
* A main class of alerting storm topology
|
||||
*
|
||||
* <p>This class provides helper function to build an alerting topology and
|
||||
* provides main function that is executed during submission of a storm topology.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngineBolt
|
||||
* @see AlertingKafkaWriterBolt
|
||||
*
|
||||
*/
|
||||
public class AlertingStorm {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
private static final String KAFKA_SPOUT = "kafka-spout";
|
||||
|
||||
@@ -10,13 +10,27 @@ import uk.co.gresearch.siembol.alerts.common.AlertingEngine;
|
||||
import uk.co.gresearch.siembol.alerts.common.AlertingResult;
|
||||
import uk.co.gresearch.siembol.alerts.compiler.AlertingCorrelationRulesCompiler;
|
||||
import uk.co.gresearch.siembol.common.model.AlertingStormAttributesDto;
|
||||
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static org.apache.storm.utils.TupleUtils.isTick;
|
||||
import static org.apache.storm.utils.TupleUtils.putTickFrequencyIntoComponentConfig;
|
||||
|
||||
/**
|
||||
* An object for integration of a correlation alerting engine into a storm bolt
|
||||
*
|
||||
* <p>This class extends a Storm AlertingBolt class to implement a Storm bolt, that
|
||||
* evaluates events using an correlation engine initialised form the rules cached in the ZooKeeper,
|
||||
* watches for the rules update in ZooKeeper and updates the rules without need to restart the topology or the bolt,
|
||||
* emits alerts and exceptions after matching.
|
||||
* It cleans regularly internal state of counters by calling clean method of the alerting engine.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertingEngine
|
||||
* @see ZooKeeperConnector
|
||||
*
|
||||
*/
|
||||
public class CorrelationAlertingEngineBolt extends AlertingEngineBolt {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.storm;
|
||||
|
||||
/**
|
||||
* An enum of tuple field names used in alerting storm topology
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*
|
||||
* @see #EVENT
|
||||
* @see #ALERTING_MATCHES
|
||||
* @see #CORRELATION_KEY
|
||||
* @see #ALERTING_EXCEPTIONS
|
||||
* @see #CORRELATION_KEY
|
||||
*
|
||||
*/
|
||||
public enum TupleFieldNames {
|
||||
EVENT("event"),
|
||||
ALERTING_MATCHES("matches"),
|
||||
|
||||
@@ -8,7 +8,15 @@ import java.io.Serializable;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A serializable object for representing an alerting message after triggering by an alerting engine
|
||||
*
|
||||
* <p>This class implements serializable interface and is used for representing an alerting message after
|
||||
* being triggered by an alerting engine.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
*
|
||||
*/
|
||||
public class AlertMessage implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String MISSING_FIELDS_MSG = "Missing siembol alerting fields in alert: %s";
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.storm.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A serializable object for representing list of alerting messages after triggering by an alerting engine
|
||||
*
|
||||
* <p>This class implements serializable interface and is used for representing list of alerting messages after
|
||||
* being triggered by an alerting engine.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see AlertMessage
|
||||
*
|
||||
*/
|
||||
public class AlertMessages extends ArrayList<AlertMessage> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
package uk.co.gresearch.siembol.alerts.storm.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A serializable object for representing list of exceptions
|
||||
*
|
||||
* <p>This class implements serializable interface and is used for representing list of exception messages
|
||||
* as json string of an ErrorMessage.
|
||||
*
|
||||
* @author Marian Novotny
|
||||
* @see uk.co.gresearch.siembol.common.error.ErrorMessage
|
||||
*
|
||||
*/
|
||||
public class ExceptionMessages extends ArrayList<String> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user