Adding metrics into Siembol (#572)

* inti commit for siembol metrics

* adding missed files

* fixing parsing application bolt

* Reworking response metrics to use common library

* fixing metrics names

* using rule name in alertign metrics instead of full rule name

* improving parsing storm tests

* improving alerting tests

* improving enrichment tests

* improving response tests

* increasing app version

* change siembol version

* increasing siembol app version

* renaming metrics

* bug fixing
This commit is contained in:
Marian Novotny
2022-03-21 15:42:57 +00:00
committed by GitHub
parent dd5bde5eb9
commit d281c86c4a
90 changed files with 1503 additions and 627 deletions

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -35,7 +35,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -23,7 +23,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>jackson-databind</artifactId>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -51,7 +51,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@@ -16,6 +16,10 @@ import org.apache.storm.tuple.Values;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.constants.SiembolConstants;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.*;
import uk.co.gresearch.siembol.alerts.common.EvaluationResult;
@@ -31,8 +35,6 @@ import java.lang.invoke.MethodHandles;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import static java.lang.Integer.min;
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";
@@ -54,17 +56,22 @@ public class AlertingEngineBolt extends BaseRichBolt {
private OutputCollector collector;
private ZooKeeperCompositeConnector zooKeeperConnector;
private SiembolMetricsRegistrar metricsRegistrar;
private final ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory;
private final ZooKeeperAttributesDto zookeperAttributes;
private final ZooKeeperAttributesDto zooKeeperAttributes;
private final StormMetricsRegistrarFactory metricsFactory;
AlertingEngineBolt(AlertingStormAttributesDto attributes,
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory) {
this.zookeperAttributes = attributes.getZookeperAttributes();
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
this.zooKeeperAttributes = attributes.getZookeperAttributes();
this.zooKeeperConnectorFactory = zooKeeperConnectorFactory;
this.metricsFactory = metricsFactory;
}
AlertingEngineBolt(AlertingStormAttributesDto attributes) {
this(attributes, new ZooKeeperCompositeConnectorFactoryImpl());
this(attributes, new ZooKeeperCompositeConnectorFactoryImpl(), new StormMetricsRegistrarFactoryImpl());
}
@SuppressWarnings("rawtypes")
@@ -73,7 +80,8 @@ public class AlertingEngineBolt extends BaseRichBolt {
this.collector = outputCollector;
try {
LOG.info(ENGINE_INIT_START);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zookeperAttributes);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes);
metricsRegistrar = metricsFactory.createSiembolMetricsRegistrar(topologyContext);
updateRules();
if (AlertingEngine.get() == null) {
@@ -99,10 +107,11 @@ public class AlertingEngineBolt extends BaseRichBolt {
AlertingEngine engine = getAlertingEngine(rulesList);
AlertingEngine.set(engine);
metricsRegistrar.registerCounter(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()).increment();
LOG.info(ENGINE_UPDATE_COMPLETED);
} catch (Exception e) {
LOG.error(UPDATE_EXCEPTION_LOG, ExceptionUtils.getStackTrace(e));
return;
metricsRegistrar.registerCounter(SiembolMetrics.ALERTING_RULES_ERROR_UPDATE.getMetricName()).increment();
}
}

View File

@@ -12,6 +12,8 @@ import uk.co.gresearch.siembol.alerts.common.AlertingResult;
import uk.co.gresearch.siembol.alerts.protection.RuleProtectionSystem;
import uk.co.gresearch.siembol.alerts.protection.RuleProtectionSystemImpl;
import uk.co.gresearch.siembol.alerts.storm.model.*;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.model.AlertingStormAttributesDto;
import uk.co.gresearch.siembol.common.storm.KafkaWriterAnchor;
import uk.co.gresearch.siembol.common.storm.KafkaWriterBoltBase;
@@ -33,8 +35,8 @@ public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
private final String correlationTopic;
private RuleProtectionSystem ruleProtection;
public AlertingKafkaWriterBolt(AlertingStormAttributesDto attributes) {
super(attributes.getKafkaProducerProperties().getProperties());
public AlertingKafkaWriterBolt(AlertingStormAttributesDto attributes, StormMetricsRegistrarFactory metricsFactory) {
super(attributes.getKafkaProducerProperties().getProperties(), metricsFactory);
this.outputTopic = attributes.getOutputTopic();
this.errorTopic = attributes.getKafkaErrorTopic();
this.correlationTopic = attributes.getCorrelationOutputTopic();
@@ -57,7 +59,10 @@ public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
throw new IllegalStateException(WRONG_EXCEPTION_FIELD_MESSAGE);
}
ExceptionMessages exceptions = (ExceptionMessages)exceptionsObject;
var messages = new ArrayList<KafkaWriterMessage>();
var counters = new ArrayList<String>();
exceptions.forEach(x -> counters.add(SiembolMetrics.ALERTING_ENGINE_ERROR_MATCHES.getMetricName()));
for (var match : matches) {
AlertingResult matchesInfo = ruleProtection.incrementRuleMatches(match.getFullRuleName());
@@ -70,12 +75,16 @@ public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
match.getFullRuleName(), hourlyMatches, dailyMatches, match.getAlertJson());
LOG.debug(msg);
exceptions.add(msg);
counters.add(SiembolMetrics.ALERTING_ENGINE_RULE_PROTECTION.getMetricName());
counters.add(SiembolMetrics.ALERTING_RULE_PROTECTION.getMetricName(match.getRuleName()));
continue;
}
if (match.isVisibleAlert()) {
LOG.debug(SEND_MSG_LOG, match.getAlertJson(), outputTopic);
messages.add(new KafkaWriterMessage(outputTopic, match.getAlertJson()));
counters.add(SiembolMetrics.ALERTING_ENGINE_MATCHES.getMetricName());
counters.add(SiembolMetrics.ALERTING_RULE_MATCHES.getMetricName(match.getRuleName()));
}
if (match.isCorrelationAlert()) {
@@ -89,6 +98,8 @@ public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
messages.add(new KafkaWriterMessage(correlationTopic,
match.getCorrelationKey().get(),
match.getAlertJson()));
counters.add(SiembolMetrics.ALERTING_ENGINE_CORRELATION_MATCHES.getMetricName());
counters.add(SiembolMetrics.ALERTING_RULE_CORRELATION_MATCHES.getMetricName(match.getRuleName()));
}
}
@@ -99,7 +110,7 @@ public class AlertingKafkaWriterBolt extends KafkaWriterBoltBase {
}
var anchor = new KafkaWriterAnchor(tuple);
super.writeMessages(messages, anchor);
super.writeMessages(messages, counters, anchor);
}
@Override

View File

@@ -12,6 +12,8 @@ import org.apache.storm.tuple.Values;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormAttributesDto;
import uk.co.gresearch.siembol.common.storm.StormHelper;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
@@ -52,7 +54,8 @@ public class AlertingStorm {
}
public static StormTopology createTopology(AlertingStormAttributesDto attributes,
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory) {
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(KAFKA_SPOUT,
@@ -60,18 +63,20 @@ public class AlertingStorm {
attributes.getKafkaSpoutNumExecutors());
builder.setBolt(AlertingEngineType.SIEMBOL_ALERTS.getEngineName(),
new AlertingEngineBolt(attributes, zooKeeperConnectorFactory), attributes.getAlertingEngineBoltNumExecutors())
new AlertingEngineBolt(attributes, zooKeeperConnectorFactory, metricsFactory),
attributes.getAlertingEngineBoltNumExecutors())
.localOrShuffleGrouping(KAFKA_SPOUT);
builder.setBolt(KAFKA_WRITER,
new AlertingKafkaWriterBolt(attributes), attributes.getKafkaWriterBoltNumExecutors())
new AlertingKafkaWriterBolt(attributes, metricsFactory), attributes.getKafkaWriterBoltNumExecutors())
.localOrShuffleGrouping(AlertingEngineType.SIEMBOL_ALERTS.getEngineName());
return builder.createTopology();
}
public static StormTopology createCorrelationAlertingTopology(AlertingStormAttributesDto attributes,
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory) {
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(KAFKA_SPOUT,
@@ -79,12 +84,12 @@ public class AlertingStorm {
attributes.getKafkaSpoutNumExecutors());
builder.setBolt(AlertingEngineType.SIEMBOL_CORRELATION_ALERTS.getEngineName(),
new CorrelationAlertingEngineBolt(attributes, zooKeeperConnectorFactory),
new CorrelationAlertingEngineBolt(attributes, zooKeeperConnectorFactory, metricsFactory),
attributes.getAlertingEngineBoltNumExecutors())
.fieldsGrouping(KAFKA_SPOUT, new Fields(TupleFieldNames.CORRELATION_KEY.toString()));
builder.setBolt(KAFKA_WRITER,
new AlertingKafkaWriterBolt(attributes), attributes.getKafkaWriterBoltNumExecutors())
new AlertingKafkaWriterBolt(attributes, metricsFactory), attributes.getKafkaWriterBoltNumExecutors())
.localOrShuffleGrouping(AlertingEngineType.SIEMBOL_CORRELATION_ALERTS.getEngineName());
return builder.createTopology();
@@ -106,11 +111,12 @@ public class AlertingStorm {
Config config = new Config();
config.putAll(attributes.getStormAttributes().getStormConfig().getRawMap());
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory = new ZooKeeperCompositeConnectorFactoryImpl();
StormMetricsRegistrarFactory metricsFactory = new StormMetricsRegistrarFactoryImpl();
StormTopology topology = engineType == AlertingEngineType.SIEMBOL_ALERTS
? createTopology(attributes, zooKeeperConnectorFactory)
: createCorrelationAlertingTopology(attributes, zooKeeperConnectorFactory);
? createTopology(attributes, zooKeeperConnectorFactory, metricsFactory)
: createCorrelationAlertingTopology(attributes, zooKeeperConnectorFactory, metricsFactory);
String topologyName = attributes.getTopologyName() != null
? attributes.getTopologyName()
: engineType.toString();

View File

@@ -4,6 +4,7 @@ import org.apache.storm.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
import uk.co.gresearch.siembol.alerts.common.AlertingEngine;
import uk.co.gresearch.siembol.alerts.common.AlertingResult;
@@ -22,8 +23,9 @@ public class CorrelationAlertingEngineBolt extends AlertingEngineBolt {
private final int cleanIntervalSec;
public CorrelationAlertingEngineBolt(AlertingStormAttributesDto attributes,
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory) {
super(attributes, zooKeeperConnectorFactory);
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
super(attributes, zooKeeperConnectorFactory, metricsFactory);
cleanIntervalSec = attributes.getAlertingEngineCleanIntervalSec();
}

View File

@@ -22,6 +22,7 @@ public class AlertMessage implements Serializable {
}
private final String fullRuleName;
private final String ruleName;
private final Number maxHourMatches;
private final Number maxDayMatches;
private final String alertJson;
@@ -33,6 +34,7 @@ public class AlertMessage implements Serializable {
flags = EnumSet.noneOf(Flags.class);
if (engineType.equals(AlertingEngineType.SIEMBOL_CORRELATION_ALERTS)) {
fullRuleName = alert.get(AlertingFields.FULL_RULE_NAME.getCorrelationAlertingName()).toString();
ruleName = alert.get(AlertingFields.RULE_NAME.getCorrelationAlertingName()).toString();
maxHourMatches = (Number)alert.get(AlertingFields.MAX_PER_HOUR_FIELD.getCorrelationAlertingName());
maxDayMatches = (Number)alert.get(AlertingFields.MAX_PER_DAY_FIELD.getCorrelationAlertingName());
@@ -40,6 +42,7 @@ public class AlertMessage implements Serializable {
flags.add(Flags.VISIBLE_ALERT);
} else {
fullRuleName = alert.get(AlertingFields.FULL_RULE_NAME.getAlertingName()).toString();
ruleName = alert.get(AlertingFields.RULE_NAME.getAlertingName()).toString();
maxHourMatches = (Number)alert.get(AlertingFields.MAX_PER_HOUR_FIELD.getAlertingName());
maxDayMatches = (Number)alert.get(AlertingFields.MAX_PER_DAY_FIELD.getAlertingName());
@@ -99,4 +102,7 @@ public class AlertMessage implements Serializable {
return Optional.ofNullable(correlationKey);
}
public String getRuleName() {
return ruleName;
}
}

View File

@@ -13,6 +13,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
@@ -25,9 +27,7 @@ import java.io.IOException;
import java.util.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
public class AlertingEngineBoltTest {
@@ -113,19 +113,21 @@ public class AlertingEngineBoltTest {
private Tuple tuple;
private OutputCollector collector;
AlertingEngineBolt AlertingEngineBolt;
AlertingStormAttributesDto stormAttributes;
ZooKeeperAttributesDto zookeperAttributes;
private AlertingEngineBolt AlertingEngineBolt;
private AlertingStormAttributesDto stormAttributes;
private ZooKeeperAttributesDto zooKeeperAttributes;
ZooKeeperCompositeConnector zooKeeperConnector;
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory;
ArgumentCaptor<Values> argumentEmitCaptor;
private ZooKeeperCompositeConnector zooKeeperConnector;
private ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory;
private ArgumentCaptor<Values> argumentEmitCaptor;
private ArgumentCaptor<Runnable> zooKeeperCallback;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
stormAttributes = new AlertingStormAttributesDto();
zookeperAttributes = new ZooKeeperAttributesDto();
stormAttributes.setZookeperAttributes(zookeperAttributes);
zooKeeperAttributes = new ZooKeeperAttributesDto();
stormAttributes.setZookeperAttributes(zooKeeperAttributes);
tuple = Mockito.mock(Tuple.class);
collector = Mockito.mock(OutputCollector.class);
@@ -133,14 +135,24 @@ public class AlertingEngineBoltTest {
zooKeeperConnectorFactory = Mockito.mock(ZooKeeperCompositeConnectorFactory.class);
zooKeeperConnector = Mockito.mock(ZooKeeperCompositeConnector.class);
when(zooKeeperConnectorFactory.createZookeeperConnector(zookeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnector.getData()).thenReturn(Collections.singletonList(simpleTestRules));
zooKeeperCallback = ArgumentCaptor.forClass(Runnable.class);
doNothing().when(zooKeeperConnector).addCacheListener(zooKeeperCallback.capture());
when(tuple.getStringByField(eq(TupleFieldNames.EVENT.toString()))).thenReturn(event.trim());
when(collector.emit(eq(tuple), argumentEmitCaptor.capture())).thenReturn(new ArrayList<>());
AlertingEngineBolt = new AlertingEngineBolt(stormAttributes, zooKeeperConnectorFactory);
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
AlertingEngineBolt = new AlertingEngineBolt(stormAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
AlertingEngineBolt.prepare(null, null, collector);
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
}
@Test
@@ -152,7 +164,7 @@ public class AlertingEngineBoltTest {
Assert.assertTrue(values.get(0) instanceof AlertMessages);
Assert.assertTrue(values.get(1) instanceof ExceptionMessages);
AlertMessages alerts = (AlertMessages) values.get(0);
AlertMessages alerts = (AlertMessages)values.get(0);
Assert.assertEquals(1, alerts.size());
Assert.assertTrue(alerts.get(0).isVisibleAlert());
Assert.assertEquals("siembol_alert_generic_v1", alerts.get(0).getFullRuleName());
@@ -174,6 +186,9 @@ public class AlertingEngineBoltTest {
@Test
public void testNoMatchRule() {
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
when(tuple.getStringByField(eq(TupleFieldNames.EVENT.toString())))
.thenReturn(event.replaceAll("is_alert", "unknown"));
@@ -194,7 +209,7 @@ public class AlertingEngineBoltTest {
Assert.assertTrue(values.get(0) instanceof AlertMessages);
Assert.assertTrue(values.get(1) instanceof ExceptionMessages);
AlertMessages alerts = (AlertMessages) values.get(0);
AlertMessages alerts = (AlertMessages)values.get(0);
Assert.assertEquals(1, alerts.size());
Assert.assertTrue(alerts.get(0).isCorrelationAlert());
Assert.assertFalse(alerts.get(0).isVisibleAlert());
@@ -228,8 +243,31 @@ public class AlertingEngineBoltTest {
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof AlertMessages);
Assert.assertTrue(values.get(1) instanceof ExceptionMessages);
Assert.assertTrue(((AlertMessages) values.get(0)).isEmpty());
Assert.assertEquals(1, ((ExceptionMessages) values.get(1)).size());
Assert.assertTrue(((ExceptionMessages) values.get(1)).get(0).contains("JsonParseException"));
Assert.assertTrue(((AlertMessages)values.get(0)).isEmpty());
Assert.assertEquals(1, ((ExceptionMessages)values.get(1)).size());
Assert.assertTrue(((ExceptionMessages)values.get(1)).get(0).contains("JsonParseException"));
}
@Test
public void updateOk() {
zooKeeperCallback.getValue().run();
Assert.assertEquals(2,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
zooKeeperCallback.getValue().run();
Assert.assertEquals(3,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
verify(zooKeeperConnector, times(3)).getData();
}
@Test
public void updateError() {
when(zooKeeperConnector.getData()).thenReturn(Collections.singletonList("INVALID"));
zooKeeperCallback.getValue().run();
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_ERROR_UPDATE.getMetricName()));
}
}

View File

@@ -15,6 +15,8 @@ import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.alerts.storm.model.AlertMessage;
import uk.co.gresearch.siembol.alerts.storm.model.AlertMessages;
import uk.co.gresearch.siembol.alerts.storm.model.ExceptionMessages;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.AlertingStormAttributesDto;
import java.util.List;
@@ -96,6 +98,7 @@ public class AlertingKafkaWriterBoltTest {
private AlertMessages AlertMessages;
private ExceptionMessages exceptionMessages;
private Map<String, Object> alertMap;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
@@ -113,7 +116,9 @@ public class AlertingKafkaWriterBoltTest {
when(tuple.getValueByField(eq(TupleFieldNames.ALERTING_EXCEPTIONS.toString()))).thenReturn(exceptionMessages);
kafkaRule.waitForStartup();
writerBolt = new AlertingKafkaWriterBolt(attributes);
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
writerBolt = new AlertingKafkaWriterBolt(attributes,
metricsTestRegistrarFactory::createSiembolMetricsRegistrar);
writerBolt.prepare(null, null, collector);
}
@@ -127,6 +132,10 @@ public class AlertingKafkaWriterBoltTest {
Assert.assertNotNull(outputAlert);
Assert.assertEquals(1, outputAlert.size());
Assert.assertEquals(AlertMessageStr.trim(), outputAlert.get(0).trim());
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_ENGINE_MATCHES.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_RULE_MATCHES.getMetricName("alert1")));
}
@Test
@@ -150,6 +159,14 @@ public class AlertingKafkaWriterBoltTest {
Assert.assertEquals("alerting_error", parsedException.get("error_type"));
Assert.assertEquals("error", parsedException.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertTrue(parsedException.get("message").toString().contains("The rule: alert1_v1 reaches the limit"));
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_ENGINE_MATCHES.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_RULE_MATCHES.getMetricName("alert1")));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_ENGINE_RULE_PROTECTION.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_RULE_PROTECTION.getMetricName("alert1")));
}
@Test
@@ -166,6 +183,9 @@ public class AlertingKafkaWriterBoltTest {
Assert.assertEquals("alerting_error", parsedException.get("error_type"));
Assert.assertEquals("error", parsedException.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertEquals("dummy", parsedException.get("message"));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_ENGINE_ERROR_MATCHES.getMetricName()));
}
@Test
@@ -181,5 +201,9 @@ public class AlertingKafkaWriterBoltTest {
Assert.assertNotNull(outputAlert);
Assert.assertEquals(1, outputAlert.size());
Assert.assertEquals(AlertMessageCorrelationStr.trim(), outputAlert.get(0).trim());
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_ENGINE_CORRELATION_MATCHES.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ALERTING_RULE_CORRELATION_MATCHES.getMetricName("alert1")));
}
}

View File

@@ -11,6 +11,7 @@ import org.apache.storm.generated.StormTopology;
import org.junit.*;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
import uk.co.gresearch.siembol.alerts.common.AlertingFields;
@@ -119,7 +120,10 @@ public class AlertingStormApplicationTest {
.put("bootstrap.servers", bootstrapServer);
kafkaRule.waitForStartup();
topology = AlertingStorm.createTopology(alertingStormAttributes, zooKeeperConnectorFactory);
topology = AlertingStorm.createTopology(alertingStormAttributes,
zooKeeperConnectorFactory,
new StormMetricsRegistrarFactoryImpl());
LocalCluster cluster = new LocalCluster();
Config config = new Config();
config.put(Config.TOPOLOGY_DEBUG, true);

View File

@@ -11,6 +11,7 @@ import org.apache.storm.generated.StormTopology;
import org.junit.*;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
import uk.co.gresearch.siembol.alerts.common.AlertingFields;
@@ -158,7 +159,9 @@ public class CorrelationAlertingTest {
.put("bootstrap.servers", bootstrapServer);
kafkaRule.waitForStartup();
topology = AlertingStorm.createCorrelationAlertingTopology(alertingStormAttributes, zooKeeperConnectorFactory);
topology = AlertingStorm.createCorrelationAlertingTopology(alertingStormAttributes,
zooKeeperConnectorFactory,
new StormMetricsRegistrarFactoryImpl());
LocalCluster cluster = new LocalCluster();
Config config = new Config();
config.put(Config.TOPOLOGY_DEBUG, true);

View File

@@ -13,6 +13,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperCompositeConnectorFactory;
@@ -26,9 +28,7 @@ import java.io.IOException;
import java.util.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
public class CorrelationEngineBoltTest {
@@ -110,20 +110,22 @@ public class CorrelationEngineBoltTest {
private Tuple tuple;
private OutputCollector collector;
CorrelationAlertingEngineBolt correlationAlertingEngineBolt;
AlertingStormAttributesDto stormAttributes;
ZooKeeperAttributesDto zookeperAttributes;
private CorrelationAlertingEngineBolt correlationAlertingEngineBolt;
private AlertingStormAttributesDto stormAttributes;
private ZooKeeperAttributesDto zooKeeperAttributes;
ZooKeeperCompositeConnector zooKeeperConnector;
ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory;
ArgumentCaptor<Values> argumentEmitCaptor;
private ArgumentCaptor<Runnable> zooKeeperCallback;
private ZooKeeperCompositeConnector zooKeeperConnector;
private ZooKeeperCompositeConnectorFactory zooKeeperConnectorFactory;
private ArgumentCaptor<Values> argumentEmitCaptor;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
stormAttributes = new AlertingStormAttributesDto();
stormAttributes.setAlertingEngineCleanIntervalSec(1000);
zookeperAttributes = new ZooKeeperAttributesDto();
stormAttributes.setZookeperAttributes(zookeperAttributes);
zooKeeperAttributes = new ZooKeeperAttributesDto();
stormAttributes.setZookeperAttributes(zooKeeperAttributes);
tuple = Mockito.mock(Tuple.class);
collector = Mockito.mock(OutputCollector.class);
@@ -131,14 +133,23 @@ public class CorrelationEngineBoltTest {
zooKeeperConnectorFactory = Mockito.mock(ZooKeeperCompositeConnectorFactory.class);
zooKeeperConnector = Mockito.mock(ZooKeeperCompositeConnector.class);
when(zooKeeperConnectorFactory.createZookeeperConnector(zookeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnector.getData()).thenReturn(Arrays.asList(simpleCorrelationRules));
zooKeeperCallback = ArgumentCaptor.forClass(Runnable.class);
doNothing().when(zooKeeperConnector).addCacheListener(zooKeeperCallback.capture());
when(tuple.getStringByField(eq(TupleFieldNames.EVENT.toString()))).thenReturn(alert1, alert2, alert1);
when(collector.emit(eq(tuple), argumentEmitCaptor.capture())).thenReturn(new ArrayList<>());
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
correlationAlertingEngineBolt = new CorrelationAlertingEngineBolt(stormAttributes, zooKeeperConnectorFactory);
correlationAlertingEngineBolt = new CorrelationAlertingEngineBolt(stormAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
correlationAlertingEngineBolt.prepare(null, null, collector);
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
}
@Test
@@ -199,6 +210,29 @@ public class CorrelationEngineBoltTest {
correlationAlertingEngineBolt.execute(tuple);
}
verify(collector, times(10)).ack(eq(tuple));
verify(collector, never()).emit(ArgumentMatchers.<List<Object>>any());
verify(collector, never()).emit(ArgumentMatchers.any());
}
@Test
public void updateOk() {
zooKeeperCallback.getValue().run();
Assert.assertEquals(2,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
zooKeeperCallback.getValue().run();
Assert.assertEquals(3,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
verify(zooKeeperConnector, times(3)).getData();
}
@Test
public void updateError() {
when(zooKeeperConnector.getData()).thenReturn(Collections.singletonList("INVALID"));
zooKeeperCallback.getValue().run();
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_UPDATE.getMetricName()));
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ALERTING_RULES_ERROR_UPDATE.getMetricName()));
}
}

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<modules>
<module>alerting-core</module>

View File

@@ -9,13 +9,13 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencyManagement>
<dependencies>
@@ -56,7 +56,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -67,22 +67,22 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor-services</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor-sync</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -93,7 +93,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing-app</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -104,7 +104,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>enriching-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -115,7 +115,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>responding-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@@ -10,7 +10,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -41,32 +41,32 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing-app</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>enriching-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>responding-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -20,17 +20,17 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>config-editor-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing-app</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<modules>
<module>config-editor-core</module>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencyManagement>
@@ -43,7 +43,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>enriching</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -35,12 +35,12 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>

View File

@@ -10,6 +10,7 @@ import java.util.stream.Collectors;
public class EnrichmentCommand implements Serializable {
private static final long serialVersionUID = 1L;
private String ruleName;
private String tableName;
private String key;
private ArrayList<Pair<String, String>> tags;
@@ -62,4 +63,12 @@ public class EnrichmentCommand implements Serializable {
}
throw new IllegalArgumentException();
}
public String getRuleName() {
return ruleName;
}
public void setRuleName(String ruleName) {
this.ruleName = ruleName;
}
}

View File

@@ -43,6 +43,7 @@ public class EnrichingRule extends Rule {
ret.setTableName(tableName);
ret.setTags(enrichmentTags);
ret.setEnrichmentFields(enrichmentFields);
ret.setRuleName(getRuleName());
return Optional.of(ret);
}

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>enriching</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -75,7 +75,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>enriching-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@@ -14,6 +14,11 @@ import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.constants.SiembolConstants;
import uk.co.gresearch.siembol.common.error.ErrorMessage;
import uk.co.gresearch.siembol.common.error.ErrorType;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsCachedRegistrar;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
@@ -49,18 +54,23 @@ public class EnrichmentEvaluatorBolt extends BaseRichBolt {
protected static final String COMPILER_EXCEPTION_MSG_FORMAT = "Exception during enriching rules compilation: %s";
protected final AtomicReference<EnrichmentEvaluator> enrichmentEvaluator = new AtomicReference<>();
private SiembolMetricsRegistrar metricsRegistrar;
private OutputCollector collector;
private ZooKeeperConnector zooKeeperConnector;
private final ZooKeeperAttributesDto zooKeeperAttributes;
private final ZooKeeperConnectorFactory zooKeeperConnectorFactory;
private final StormMetricsRegistrarFactory metricsFactory;
EnrichmentEvaluatorBolt(StormEnrichmentAttributesDto attributes, ZooKeeperConnectorFactory zooKeeperConnectorFactory) {
EnrichmentEvaluatorBolt(StormEnrichmentAttributesDto attributes,
ZooKeeperConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
this.zooKeeperAttributes = attributes.getEnrichingRulesZookeperAttributes();
this.zooKeeperConnectorFactory = zooKeeperConnectorFactory;
this.metricsFactory = metricsFactory;
}
public EnrichmentEvaluatorBolt(StormEnrichmentAttributesDto attributes) {
this(attributes, new ZooKeeperConnectorFactoryImpl());
this(attributes, new ZooKeeperConnectorFactoryImpl(), new StormMetricsRegistrarFactoryImpl());
}
@Override
@@ -69,6 +79,7 @@ public class EnrichmentEvaluatorBolt extends BaseRichBolt {
try {
LOG.info(ENGINE_INIT_START);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes);
metricsRegistrar = metricsFactory.createSiembolMetricsRegistrar(topologyContext);
updateRules();
if (enrichmentEvaluator.get() == null) {
@@ -93,9 +104,10 @@ public class EnrichmentEvaluatorBolt extends BaseRichBolt {
EnrichmentEvaluator engine = getEnrichmentEvaluator(rules);
enrichmentEvaluator.set(engine);
metricsRegistrar.registerCounter(SiembolMetrics.ENRICHMENT_RULES_UPDATE.getMetricName()).increment();
LOG.info(ENGINE_UPDATE_COMPLETED);
} catch (Exception e) {
metricsRegistrar.registerCounter(SiembolMetrics.ENRICHMENT_RULES_ERROR_UPDATE.getMetricName()).increment();
LOG.error(UPDATE_EXCEPTION_LOG, ExceptionUtils.getStackTrace(e));
}
}

View File

@@ -14,6 +14,7 @@ import uk.co.gresearch.siembol.common.error.ErrorType;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessage;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessages;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.enrichments.evaluation.EnrichmentEvaluatorLibrary;
import uk.co.gresearch.siembol.enrichments.storm.common.EnrichmentTuples;
import uk.co.gresearch.siembol.enrichments.storm.common.EnrichmentPairs;
@@ -64,12 +65,21 @@ public class EnrichmentMergerBolt extends BaseRichBolt {
}
EnrichmentExceptions exceptions = (EnrichmentExceptions)exceptionsObj;
Object countersObj = tuple.getValueByField(EnrichmentTuples.COUNTERS.toString());
if (!(countersObj instanceof SiembolMetricsCounters)) {
LOG.error(INVALID_TYPE_IN_TUPLES);
throw new IllegalArgumentException(INVALID_TYPE_IN_TUPLES);
}
var counters = new SiembolMetricsCounters();
counters.addAll((SiembolMetricsCounters)countersObj);
try {
event = EnrichmentEvaluatorLibrary.mergeEnrichments(event,
enrichments,
Optional.of(SiembolMessageFields.ENRICHING_TIME.toString()));
} catch (Exception e) {
LOG.error(MERGING_ERROR, event, enrichments.toString());
LOG.error(MERGING_ERROR, event, enrichments);
exceptions.add(ErrorMessage.createErrorMessage(e, ErrorType.ENRICHMENT_ERROR).toString());
}
@@ -77,12 +87,12 @@ public class EnrichmentMergerBolt extends BaseRichBolt {
KafkaWriterMessages messages = new KafkaWriterMessages();
messages.add(new KafkaWriterMessage(outputTopic, event));
exceptions.forEach(x -> messages.add(new KafkaWriterMessage(errorTopic, x)));
collector.emit(tuple, new Values(messages));
collector.emit(tuple, new Values(messages, counters));
collector.ack(tuple);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(EnrichmentTuples.KAFKA_MESSAGES.toString()));
declarer.declare(new Fields(EnrichmentTuples.KAFKA_MESSAGES.toString(), EnrichmentTuples.COUNTERS.toString()));
}
}

View File

@@ -19,10 +19,16 @@ import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystem;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystemFactory;
import uk.co.gresearch.siembol.common.filesystem.SupportedFileSystem;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.EnrichmentTableDto;
import uk.co.gresearch.siembol.common.model.EnrichmentTablesUpdateDto;
import uk.co.gresearch.siembol.common.model.StormEnrichmentAttributesDto;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactoryImpl;
@@ -63,22 +69,27 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
private final ZooKeeperAttributesDto zooKeeperAttributesDto;
private final ZooKeeperConnectorFactory zooKeeperConnectorFactory;
private final SiembolFileSystemFactory fileSystemFactory;
private final StormMetricsRegistrarFactory metricsFactory;
private OutputCollector collector;
private ZooKeeperConnector zooKeeperConnector;
private SiembolMetricsRegistrar metricsRegistrar;
MemoryTableEnrichmentBolt(StormEnrichmentAttributesDto attributes,
ZooKeeperConnectorFactory zooKeeperConnectorFactory,
SiembolFileSystemFactory fileSystemFactory) {
SiembolFileSystemFactory fileSystemFactory,
StormMetricsRegistrarFactory metricsFactory) {
this.zooKeeperAttributesDto = attributes.getEnrichingTablesAttributes();
this.zooKeeperConnectorFactory = zooKeeperConnectorFactory;
this.fileSystemFactory = fileSystemFactory;
this.metricsFactory = metricsFactory;
}
public MemoryTableEnrichmentBolt(StormEnrichmentAttributesDto attributes) {
this(attributes,
new ZooKeeperConnectorFactoryImpl(),
SupportedFileSystem.fromUri(attributes.getEnrichingTablesUri()));
SupportedFileSystem.fromUri(attributes.getEnrichingTablesUri()),
new StormMetricsRegistrarFactoryImpl());
}
@Override
@@ -88,6 +99,7 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
try {
LOG.info(TABLES_INIT_START);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributesDto);
metricsRegistrar = metricsFactory.createSiembolMetricsRegistrar(topologyContext);
updateTables();
if (enrichmentTables.isEmpty()) {
@@ -123,11 +135,17 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
var memoryTable = EnrichmentMemoryTable.fromJsonStream(is);
enrichmentTables.put(table.getName(), ImmutablePair.of(table.getPath(), memoryTable));
LOG.info(TABLE_INIT_COMPLETED, table.getName());
metricsRegistrar
.registerCounter(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName(table.getName()))
.increment();
} catch (Exception e) {
LOG.error(TABLE_UPDATE_EXCEPTION_FORMAT,
table.getName(),
table.getPath(),
ExceptionUtils.getStackTrace(e));
metricsRegistrar.registerCounter(
SiembolMetrics.ENRICHMENT_TABLE_UPDATE_ERROR.getMetricName(table.getName()))
.increment();
}
}
}
@@ -157,6 +175,7 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
EnrichmentExceptions exceptions = (EnrichmentExceptions)exceptionsObj;
EnrichmentPairs enrichments = new EnrichmentPairs();
SiembolMetricsCounters counters = new SiembolMetricsCounters();
for (EnrichmentCommand command : commands) {
var tablePair = enrichmentTables.get(command.getTableName());
@@ -165,9 +184,14 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
}
Optional<List<Pair<String, String>>> result = tablePair.getRight().getValues(command);
result.ifPresent(enrichments::addAll);
if (result.isPresent()) {
enrichments.addAll(result.get());
counters.add(SiembolMetrics.ENRICHMENT_RULE_APPLIED.getMetricName(command.getRuleName()));
counters.add(SiembolMetrics.ENRICHMENT_TABLE_APPLIED.getMetricName(command.getTableName()));
}
}
collector.emit(tuple, new Values(event, enrichments, exceptions));
collector.emit(tuple, new Values(event, enrichments, exceptions, counters));
collector.ack(tuple);
}
@@ -175,6 +199,7 @@ public class MemoryTableEnrichmentBolt extends BaseRichBolt {
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(EnrichmentTuples.EVENT.toString(),
EnrichmentTuples.ENRICHMENTS.toString(),
EnrichmentTuples.EXCEPTIONS.toString()));
EnrichmentTuples.EXCEPTIONS.toString(),
EnrichmentTuples.COUNTERS.toString()));
}
}

View File

@@ -14,6 +14,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystemFactory;
import uk.co.gresearch.siembol.common.filesystem.SupportedFileSystem;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.storm.KafkaWriterBolt;
import uk.co.gresearch.siembol.common.model.StormAttributesDto;
import uk.co.gresearch.siembol.common.storm.StormHelper;
@@ -56,7 +58,8 @@ public class StormEnrichingApplication {
public static StormTopology createTopology(StormEnrichmentAttributesDto attributes,
ZooKeeperConnectorFactory zooKeeperConnectorFactory,
SiembolFileSystemFactory siembolFileSystemFactory) {
SiembolFileSystemFactory siembolFileSystemFactory,
StormMetricsRegistrarFactory metricsFactory) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(KAFKA_SPOUT,
@@ -64,12 +67,13 @@ public class StormEnrichingApplication {
attributes.getKafkaSpoutNumExecutors());
builder.setBolt(ENRICHING_ENGINE_BOLT_NAME,
new EnrichmentEvaluatorBolt(attributes, zooKeeperConnectorFactory),
new EnrichmentEvaluatorBolt(attributes, zooKeeperConnectorFactory, metricsFactory),
attributes.getEnrichingEngineBoltNumExecutors())
.localOrShuffleGrouping(KAFKA_SPOUT);
builder.setBolt(MEMORY_ENRICHING_BOLT_NAME,
new MemoryTableEnrichmentBolt(attributes, zooKeeperConnectorFactory, siembolFileSystemFactory),
new MemoryTableEnrichmentBolt(attributes, zooKeeperConnectorFactory,
siembolFileSystemFactory, metricsFactory),
attributes.getMemoryEnrichingBoltNumExecutors())
.localOrShuffleGrouping(ENRICHING_ENGINE_BOLT_NAME);
@@ -80,7 +84,9 @@ public class StormEnrichingApplication {
builder.setBolt(KAFKA_WRITER_BOLT_NAME,
new KafkaWriterBolt(attributes.getKafkaBatchWriterAttributes(),
EnrichmentTuples.KAFKA_MESSAGES.toString()),
EnrichmentTuples.KAFKA_MESSAGES.toString(),
EnrichmentTuples.COUNTERS.toString(),
metricsFactory),
attributes.getKafkaWriterBoltNumExecutors())
.localOrShuffleGrouping(MERGING_BOLT_NAME);
return builder.createTopology();
@@ -101,7 +107,8 @@ public class StormEnrichingApplication {
config.putAll(attributes.getStormAttributes().getStormConfig().getRawMap());
StormTopology topology = createTopology(attributes,
new ZooKeeperConnectorFactoryImpl(),
SupportedFileSystem.fromUri(attributes.getEnrichingTablesUri()));
SupportedFileSystem.fromUri(attributes.getEnrichingTablesUri()),
new StormMetricsRegistrarFactoryImpl());
LOG.info(SUBMIT_INFO_MSG, attributes.getTopologyName(), attributesStr);
StormSubmitter.submitTopology(attributes.getTopologyName(), config, topology);

View File

@@ -5,7 +5,8 @@ public enum EnrichmentTuples {
COMMANDS("commands"),
ENRICHMENTS("enrichments"),
EXCEPTIONS("exceptions"),
KAFKA_MESSAGES("messages");
KAFKA_MESSAGES("messages"),
COUNTERS("counters");
private final String name;
EnrichmentTuples(String name) {

View File

@@ -1,6 +1,5 @@
package uk.co.gresearch.siembol.enrichments.storm;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
@@ -9,6 +8,8 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormEnrichmentAttributesDto;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
@@ -17,7 +18,8 @@ import uk.co.gresearch.siembol.enrichments.storm.common.*;
import java.util.ArrayList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
public class EnrichmentEvaluatorBoltTest {
private final String event = """
@@ -65,12 +67,14 @@ public class EnrichmentEvaluatorBoltTest {
private Tuple tuple;
private OutputCollector collector;
EnrichmentEvaluatorBolt enrichmentEvaluatorBolt;
ZooKeeperAttributesDto zooKeeperAttributes;
StormEnrichmentAttributesDto attributes;
ZooKeeperConnector zooKeeperConnector;
ZooKeeperConnectorFactory zooKeeperConnectorFactory;
ArgumentCaptor<Values> argumentEmitCaptor;
private EnrichmentEvaluatorBolt enrichmentEvaluatorBolt;
private ZooKeeperAttributesDto zooKeeperAttributes;
private StormEnrichmentAttributesDto attributes;
private ArgumentCaptor<Runnable> zooKeeperCallback;
private ZooKeeperConnector zooKeeperConnector;
private ZooKeeperConnectorFactory zooKeeperConnectorFactory;
private ArgumentCaptor<Values> argumentEmitCaptor;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
@@ -83,16 +87,25 @@ public class EnrichmentEvaluatorBoltTest {
argumentEmitCaptor = ArgumentCaptor.forClass(Values.class);
zooKeeperConnectorFactory = Mockito.mock(ZooKeeperConnectorFactory.class);
zooKeeperConnector = Mockito.mock(ZooKeeperConnector.class);
when(zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnector.getData()).thenReturn(testRules);
zooKeeperCallback = ArgumentCaptor.forClass(Runnable.class);
doNothing().when(zooKeeperConnector).addCacheListener(zooKeeperCallback.capture());
when(tuple.getStringByField(eq(EnrichmentTuples.EVENT.toString()))).thenReturn(event);
when(collector.emit(eq(tuple), argumentEmitCaptor.capture())).thenReturn(new ArrayList<>());
enrichmentEvaluatorBolt = new EnrichmentEvaluatorBolt(attributes, zooKeeperConnectorFactory);
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
enrichmentEvaluatorBolt = new EnrichmentEvaluatorBolt(attributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
enrichmentEvaluatorBolt.prepare(null, null, collector);
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ENRICHMENT_RULES_UPDATE.getMetricName()));
}
@Test
@@ -105,13 +118,13 @@ public class EnrichmentEvaluatorBoltTest {
Assert.assertTrue(values.get(1) instanceof EnrichmentCommands);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertEquals(event, values.get(0));
EnrichmentCommands commands = (EnrichmentCommands) values.get(1);
EnrichmentCommands commands = (EnrichmentCommands)values.get(1);
Assert.assertEquals(1, commands.size());
Assert.assertEquals("tmp_string", commands.get(0).getKey());
Assert.assertEquals("tmp_string", commands.get(0).getKey());
Assert.assertEquals(1, commands.get(0).getTags().size());
Assert.assertEquals(1, commands.get(0).getEnrichmentFields().size());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
}
@Test
@@ -124,8 +137,8 @@ public class EnrichmentEvaluatorBoltTest {
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentCommands);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(((EnrichmentCommands) values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentCommands)values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
}
@Test
@@ -138,9 +151,32 @@ public class EnrichmentEvaluatorBoltTest {
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentCommands);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(((EnrichmentCommands) values.get(1)).isEmpty());
Assert.assertFalse(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertEquals(1, ((EnrichmentExceptions) values.get(2)).size());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).get(0).contains("JsonParseException"));
Assert.assertTrue(((EnrichmentCommands)values.get(1)).isEmpty());
Assert.assertFalse(((EnrichmentExceptions)values.get(2)).isEmpty());
Assert.assertEquals(1, ((EnrichmentExceptions)values.get(2)).size());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).get(0).contains("JsonParseException"));
}
@Test
public void updateOk() {
zooKeeperCallback.getValue().run();
Assert.assertEquals(2,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ENRICHMENT_RULES_UPDATE.getMetricName()));
zooKeeperCallback.getValue().run();
Assert.assertEquals(3,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ENRICHMENT_RULES_UPDATE.getMetricName()));
verify(zooKeeperConnector, times(3)).getData();
}
@Test
public void updateError() {
when(zooKeeperConnector.getData()).thenReturn("INVALID");
zooKeeperCallback.getValue().run();
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.ENRICHMENT_RULES_UPDATE.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_RULES_ERROR_UPDATE.getMetricName()));
}
}

View File

@@ -12,6 +12,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessages;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.enrichments.storm.common.EnrichmentTuples;
import uk.co.gresearch.siembol.enrichments.storm.common.EnrichmentPairs;
import uk.co.gresearch.siembol.enrichments.storm.common.EnrichmentExceptions;
@@ -39,13 +40,17 @@ public class EnrichmentMergerBoltTest {
private OutputCollector collector;
private EnrichmentExceptions exceptions;
private EnrichmentPairs enrichments;
EnrichmentMergerBolt mergerBolt;
ArgumentCaptor<Values> argumentEmitCaptor;
private SiembolMetricsCounters counters;
private EnrichmentMergerBolt mergerBolt;
private ArgumentCaptor<Values> argumentEmitCaptor;
private String testCounterName = "test_counter";
@Before
public void setUp() {
exceptions = new EnrichmentExceptions();
enrichments = new EnrichmentPairs();
counters = new SiembolMetricsCounters();
counters.add(testCounterName);
tuple = Mockito.mock(Tuple.class);
collector = Mockito.mock(OutputCollector.class);
argumentEmitCaptor = ArgumentCaptor.forClass(Values.class);
@@ -53,6 +58,7 @@ public class EnrichmentMergerBoltTest {
when(tuple.getStringByField(eq(EnrichmentTuples.EVENT.toString()))).thenReturn(event);
when(tuple.getValueByField(eq(EnrichmentTuples.ENRICHMENTS.toString()))).thenReturn(enrichments);
when(tuple.getValueByField(eq(EnrichmentTuples.EXCEPTIONS.toString()))).thenReturn(exceptions);
when(tuple.getValueByField(eq(EnrichmentTuples.COUNTERS.toString()))).thenReturn(counters);
when(collector.emit(eq(tuple), argumentEmitCaptor.capture())).thenReturn(new ArrayList<>());
StormEnrichmentAttributesDto attributes = new StormEnrichmentAttributesDto();
@@ -67,10 +73,15 @@ public class EnrichmentMergerBoltTest {
mergerBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counterValues = (SiembolMetricsCounters)values.get(1);
Assert.assertEquals(1, counterValues.size());
Assert.assertEquals("test_counter", counterValues.get(0));
Assert.assertEquals(outputTopic, messages.get(0).getTopic());
Assert.assertTrue(messages.get(0).getMessage().contains(enrichedEventPrefix.trim()));
}
@@ -82,10 +93,16 @@ public class EnrichmentMergerBoltTest {
mergerBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counterValues = (SiembolMetricsCounters)values.get(1);
Assert.assertEquals(1, counterValues.size());
Assert.assertEquals("test_counter", counterValues.get(0));
Assert.assertEquals(outputTopic, messages.get(0).getTopic());
Assert.assertFalse(messages.get(0).getMessage().isEmpty());
@@ -105,10 +122,15 @@ public class EnrichmentMergerBoltTest {
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counterValues = (SiembolMetricsCounters)values.get(1);
Assert.assertEquals(1, counterValues.size());
Assert.assertEquals("test_counter", counterValues.get(0));
Assert.assertEquals(outputTopic, messages.get(0).getTopic());
Assert.assertEquals(errorTopic, messages.get(1).getTopic());
@@ -125,10 +147,15 @@ public class EnrichmentMergerBoltTest {
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counterValues = (SiembolMetricsCounters)values.get(1);
Assert.assertEquals(1, counterValues.size());
Assert.assertEquals("test_counter", counterValues.get(0));
Assert.assertEquals(outputTopic, messages.get(0).getTopic());
Assert.assertTrue(messages.get(0).getMessage().contains("\"test\":\"enrichment\""));
}
@@ -140,10 +167,15 @@ public class EnrichmentMergerBoltTest {
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counterValues = (SiembolMetricsCounters)values.get(1);
Assert.assertEquals(1, counterValues.size());
Assert.assertEquals("test_counter", counterValues.get(0));
Assert.assertEquals(outputTopic, messages.get(0).getTopic());
Assert.assertEquals("INVALID", messages.get(0).getMessage());

View File

@@ -11,8 +11,11 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystem;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystemFactory;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormEnrichmentAttributesDto;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.common.testing.TestingZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.enrichments.common.EnrichmentCommand;
import uk.co.gresearch.siembol.enrichments.storm.common.*;
@@ -92,6 +95,7 @@ public class MemoryTableEnrichmentBoltTest {
private SiembolFileSystemFactory fileSystemFactory;
private SiembolFileSystem fileSystem;
private ArgumentCaptor<Values> argumentEmitCaptor;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
@@ -123,8 +127,17 @@ public class MemoryTableEnrichmentBoltTest {
when(fileSystem.openInputStream(eq("/siembol/tables/enrichment/different_test.json")))
.thenReturn(new ByteArrayInputStream(simpleOneField.getBytes()));
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes, zooKeeperConnectorFactory, fileSystemFactory);
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes,
zooKeeperConnectorFactory,
fileSystemFactory,
metricsTestRegistrarFactory);
memoryTableBolt.prepare(null, null, collector);
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table")));
}
@Test
@@ -132,32 +145,39 @@ public class MemoryTableEnrichmentBoltTest {
memoryTableBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(3, values.size());
Assert.assertEquals(4, values.size());
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentPairs);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(values.get(3) instanceof SiembolMetricsCounters);
Assert.assertEquals(event, values.get(0));
Assert.assertTrue(((EnrichmentPairs) values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentPairs)values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
Assert.assertTrue(((SiembolMetricsCounters)values.get(3)).isEmpty());
var counters = (SiembolMetricsCounters)values.get(3);
Assert.assertTrue(counters.isEmpty());
}
@Test
public void testNoneMptyExceptionsEmptyCommands() {
public void testNonemptyExceptionsEmptyCommands() {
exceptions.add("dummy1");
exceptions.add("dummy2");
memoryTableBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(3, values.size());
Assert.assertEquals(4, values.size());
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentPairs);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(values.get(3) instanceof SiembolMetricsCounters);
Assert.assertEquals(event, values.get(0));
Assert.assertTrue(((EnrichmentPairs) values.get(1)).isEmpty());
EnrichmentExceptions exceptions = (EnrichmentExceptions) values.get(2);
Assert.assertTrue(((EnrichmentPairs)values.get(1)).isEmpty());
EnrichmentExceptions exceptions = (EnrichmentExceptions)values.get(2);
Assert.assertEquals(2, exceptions.size());
Assert.assertEquals("dummy1", exceptions.get(0));
Assert.assertEquals("dummy2", exceptions.get(1));
var counters = (SiembolMetricsCounters)values.get(3);
Assert.assertTrue(counters.isEmpty());
}
@Test
@@ -165,16 +185,20 @@ public class MemoryTableEnrichmentBoltTest {
EnrichmentCommand command = new EnrichmentCommand();
commands.add(command);
command.setTableName("invalid");
command.setRuleName("test_rule");
memoryTableBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(3, values.size());
Assert.assertEquals(4, values.size());
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentPairs);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(values.get(3) instanceof SiembolMetricsCounters);
Assert.assertEquals(event, values.get(0));
Assert.assertTrue(((EnrichmentPairs) values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentPairs)values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
var counters = (SiembolMetricsCounters)values.get(3);
Assert.assertTrue(counters.isEmpty());
}
@Test
@@ -184,17 +208,23 @@ public class MemoryTableEnrichmentBoltTest {
command.setTableName("test_table");
command.setKey("1.2.3.1");
command.setTags(new ArrayList<>(Arrays.asList(Pair.of("is_test", "true"))));
command.setRuleName("test_rule");
memoryTableBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(3, values.size());
Assert.assertEquals(4, values.size());
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentPairs);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(values.get(3) instanceof SiembolMetricsCounters);
Assert.assertEquals(event, values.get(0));
EnrichmentPairs enrichments = (EnrichmentPairs) values.get(1);
EnrichmentPairs enrichments = (EnrichmentPairs)values.get(1);
Assert.assertEquals(1, enrichments.size());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
var counters = (SiembolMetricsCounters)values.get(3);
Assert.assertEquals(2, counters.size());
Assert.assertTrue(counters.contains(SiembolMetrics.ENRICHMENT_TABLE_APPLIED.getMetricName("test_table")));
Assert.assertTrue(counters.contains(SiembolMetrics.ENRICHMENT_RULE_APPLIED.getMetricName("test_rule")));
}
@Test
@@ -203,16 +233,19 @@ public class MemoryTableEnrichmentBoltTest {
commands.add(command);
command.setTableName("test_table");
command.setKey("unknown");
command.setRuleName("test_rule");
memoryTableBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(3, values.size());
Assert.assertEquals(4, values.size());
Assert.assertTrue(values.get(0) instanceof String);
Assert.assertTrue(values.get(1) instanceof EnrichmentPairs);
Assert.assertTrue(values.get(2) instanceof EnrichmentExceptions);
Assert.assertTrue(values.get(3) instanceof SiembolMetricsCounters);
Assert.assertEquals(event, values.get(0));
Assert.assertTrue(((EnrichmentPairs) values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions) values.get(2)).isEmpty());
Assert.assertTrue(((EnrichmentPairs)values.get(1)).isEmpty());
Assert.assertTrue(((EnrichmentExceptions)values.get(2)).isEmpty());
Assert.assertTrue(((SiembolMetricsCounters)values.get(3)).isEmpty());
}
@Test
@@ -222,6 +255,12 @@ public class MemoryTableEnrichmentBoltTest {
.openInputStream(eq("/siembol/tables/enrichment/test.json"));
Mockito.verify(fileSystem, times(1))
.openInputStream(eq("/siembol/tables/enrichment/test2.json"));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table")));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table_2")));
}
@Test
@@ -233,6 +272,12 @@ public class MemoryTableEnrichmentBoltTest {
.openInputStream(eq("/siembol/tables/enrichment/different_test.json"));
Mockito.verify(fileSystem, times(1))
.openInputStream(eq("/siembol/tables/enrichment/test2.json"));
Assert.assertEquals(2,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table")));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table_2")));
}
@Test
@@ -241,7 +286,10 @@ public class MemoryTableEnrichmentBoltTest {
when(fileSystemFactory.create()).thenReturn(fileSystem);
when(fileSystem.openInputStream(anyString())).thenReturn(new ByteArrayInputStream(simpleOneField.getBytes()));
zooKeeperConnectorFactory.setData(zooKeeperPath, "{}");
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes, zooKeeperConnectorFactory, fileSystemFactory);
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes,
zooKeeperConnectorFactory,
fileSystemFactory,
metricsTestRegistrarFactory);
memoryTableBolt.prepare(null, null, collector);
Mockito.verify(fileSystem, times(0)).openInputStream(anyString());
}
@@ -252,7 +300,10 @@ public class MemoryTableEnrichmentBoltTest {
fileSystem = Mockito.mock(SiembolFileSystem.class);
when(fileSystemFactory.create()).thenReturn(fileSystem);
when(fileSystem.openInputStream(anyString())).thenReturn(new ByteArrayInputStream(simpleOneField.getBytes()));
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes, zooKeeperConnectorFactory, fileSystemFactory);
memoryTableBolt = new MemoryTableEnrichmentBolt(attributes,
zooKeeperConnectorFactory,
fileSystemFactory,
metricsTestRegistrarFactory);
memoryTableBolt.prepare(null, null, collector);
Mockito.verify(fileSystem, times(0)).openInputStream(anyString());
}
@@ -269,6 +320,15 @@ public class MemoryTableEnrichmentBoltTest {
.openInputStream(eq("/siembol/tables/enrichment/different_test.json"));
Mockito.verify(fileSystem, times(1))
.openInputStream(eq("/siembol/tables/enrichment/test2.json"));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table")));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATE_ERROR.getMetricName("test_table")));
Assert.assertEquals(1,
metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.ENRICHMENT_TABLE_UPDATED.getMetricName("test_table_2")));
}
@Test(expected = RuntimeException.class)

View File

@@ -14,6 +14,7 @@ import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.filesystem.ByteArrayFileSystem;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystem;
import uk.co.gresearch.siembol.common.filesystem.SiembolFileSystemFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.model.StormEnrichmentAttributesDto;
@@ -208,7 +209,8 @@ public class StormEnrichingApplicationTest {
kafkaRule.waitForStartup();
topology = StormEnrichingApplication.createTopology(enrichmentAttributes,
zooKeeperConnectorFactory,
fileSystemFactory);
fileSystemFactory,
new StormMetricsRegistrarFactoryImpl());
LocalCluster cluster = new LocalCluster();
Config config = new Config();

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<modules>
<module>enriching-core</module>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -39,12 +39,12 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>

View File

@@ -85,19 +85,25 @@ public abstract class ParsingApplicationParser implements Serializable {
? JSON_READER.readValue(metadata.trim())
: null;
long timestamp = timeProvider.getCurrentTimeInMs();
for (ParserResult parserResult : parseInternally(source, metadata, message)) {
var currentResult = new ParsingApplicationResult(parserResult.getSourceType());
if (parserResult.getException() != null) {
ret.add(new ParsingApplicationResult(
errorTopic,
getErrorMessage(parserResult.getException(), parserResult.getSourceType(), message)));
currentResult.setResultType(ParsingApplicationResult.ResultType.ERROR);
currentResult.setTopic(errorTopic);
currentResult.setMessage(getErrorMessage(
parserResult.getException(), parserResult.getSourceType(), message));
ret.add(currentResult);
continue;
}
List<Map<String, Object>> parsed = parserResult.getParsedMessages();
currentResult.setTopic(parserResult.getTopic());
var parsed = parserResult.getParsedMessages();
parsed.removeIf(Map::isEmpty);
if (parsed.isEmpty()) {
currentResult.setResultType(ParsingApplicationResult.ResultType.FILTERED);
ret.add(currentResult);
continue;
}
@@ -123,12 +129,19 @@ public abstract class ParsingApplicationParser implements Serializable {
}
})
.collect(Collectors.toCollection(ArrayList::new));
ret.add(new ParsingApplicationResult(parserResult.getTopic(), serialised));
currentResult.setMessages(serialised);
currentResult.setResultType(ParsingApplicationResult.ResultType.PARSED);
ret.add(currentResult);
}
return ret;
} catch (Exception e) {
LOG.debug(ERROR_MESSAGE, name, new String(message), metadata, ExceptionUtils.getMessage(e));
ret.add(new ParsingApplicationResult(errorTopic, getErrorMessage(e, sourceType, message)));
var errorResult = new ParsingApplicationResult(sourceType);
errorResult.setTopic(errorTopic);
errorResult.setMessage(getErrorMessage(e, sourceType, message));
errorResult.setResultType(ParsingApplicationResult.ResultType.ERROR);
ret.add(errorResult);
return ret;
}
}

View File

@@ -4,18 +4,19 @@ import java.io.Serializable;
import java.util.ArrayList;
public class ParsingApplicationResult implements Serializable {
private static final long serialVersionUID = 1L;
private final String topic;
private final ArrayList<String> messages;
public ParsingApplicationResult(String topic, ArrayList<String> messages) {
this.topic = topic;
this.messages = messages;
public enum ResultType implements Serializable {
PARSED,
ERROR,
FILTERED
}
public ParsingApplicationResult(String topic, String message) {
this.topic = topic;
messages = new ArrayList<>();
messages.add(message);
private static final long serialVersionUID = 1L;
private final String sourceType;
private String topic;
private ArrayList<String> messages;
private ResultType resultType = ResultType.PARSED;
public ParsingApplicationResult(String sourceType) {
this.sourceType = sourceType;
}
public String getTopic() {
@@ -26,4 +27,28 @@ public class ParsingApplicationResult implements Serializable {
return messages;
}
public String getSourceType() {
return sourceType;
}
public void setMessages(ArrayList<String> messages) {
this.messages = messages;
}
public void setMessage(String message) {
this.messages = new ArrayList<>();
this.messages.add(message);
}
public void setTopic(String topic) {
this.topic = topic;
}
public ResultType getResultType() {
return resultType;
}
public void setResultType(ResultType resultType) {
this.resultType = resultType;
}
}

View File

@@ -169,7 +169,8 @@ public class SingleApplicationParserTest {
parserResult.getParsedMessages().replaceAll(x-> new HashMap<>());
when(siembolParser.parseToResult(metadata, input)).thenReturn(parserResult);
List<ParsingApplicationResult> result = appParser.parse( metadata, input);
Assert.assertTrue(result.isEmpty());
Assert.assertEquals(1, result.size());
Assert.assertNull(result.get(0).getMessages());
}
@Test
@@ -232,7 +233,9 @@ public class SingleApplicationParserTest {
List<ParsingApplicationResult> result = appParser.parse( metadata, input);
verify(timeProvider, times(1)).getCurrentTimeInMs();
verify(siembolParser, times(1)).parseToResult(metadata, input);
Assert.assertEquals(0, result.size());
Assert.assertEquals(1, result.size());
Assert.assertNull(result.get(0).getMessages());
}
@Test

View File

@@ -203,7 +203,9 @@ public class SourceRoutingApplicationParserTest {
verify(timeProvider, times(1)).getCurrentTimeInMs();
verify(routedParser1, times(1)).parseToResult(metadata, input);
Assert.assertTrue(result.isEmpty());
Assert.assertFalse(result.isEmpty());
Assert.assertEquals(1, result.size());
Assert.assertNull(result.get(0).getMessages());
}
@Test

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -45,7 +45,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -75,7 +75,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>parsing-app</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@@ -12,10 +12,15 @@ import org.apache.storm.tuple.Values;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.constants.SiembolConstants;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormParsingApplicationAttributesDto;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessage;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessages;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactoryImpl;
@@ -46,24 +51,32 @@ public class ParsingApplicationBolt extends BaseRichBolt {
private static final String INVALID_TYPE_IN_TUPLE = "Invalid type in tuple";
private final AtomicReference<ParsingApplicationParser> parsingApplicationParser = new AtomicReference<>();
private final ZooKeeperAttributesDto zookeperAttributes;
private final ZooKeeperAttributesDto zooKeeperAttributes;
private final String parsingAppSpecification;
private OutputCollector collector;
private ZooKeeperConnector zooKeeperConnector;
private SiembolMetricsRegistrar metricsRegistrar;
private final ZooKeeperConnectorFactory zooKeeperConnectorFactory;
private final StormMetricsRegistrarFactory metricsFactory;
ParsingApplicationBolt(StormParsingApplicationAttributesDto attributes,
ParsingApplicationFactoryAttributes parsingAttributes,
ZooKeeperConnectorFactory zooKeeperConnectorFactory) throws Exception {
this.zookeperAttributes = attributes.getZookeeperAttributes();
ZooKeeperConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
this.zooKeeperAttributes = attributes.getZookeeperAttributes();
this.parsingAppSpecification = parsingAttributes.getApplicationParserSpecification();
this.zooKeeperConnectorFactory = zooKeeperConnectorFactory;
this.metricsFactory = metricsFactory;
}
public ParsingApplicationBolt(StormParsingApplicationAttributesDto attributes,
ParsingApplicationFactoryAttributes parsingAttributes) throws Exception {
this(attributes, parsingAttributes, new ZooKeeperConnectorFactoryImpl());
ParsingApplicationFactoryAttributes parsingAttributes) {
this(attributes,
parsingAttributes,
new ZooKeeperConnectorFactoryImpl(),
new StormMetricsRegistrarFactoryImpl());
}
@SuppressWarnings("rawtypes")
@@ -72,12 +85,14 @@ public class ParsingApplicationBolt extends BaseRichBolt {
this.collector = outputCollector;
try {
LOG.info(INIT_START);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zookeperAttributes);
zooKeeperConnector = zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes);
metricsRegistrar = metricsFactory.createSiembolMetricsRegistrar(topologyContext);
updateParsers();
if (parsingApplicationParser.get() == null) {
throw new IllegalStateException(ERROR_INIT_MESSAGE);
}
zooKeeperConnector.addCacheListener(this::updateParsers);
LOG.info(INIT_COMPLETED);
} catch (Exception e) {
@@ -104,12 +119,12 @@ public class ParsingApplicationBolt extends BaseRichBolt {
throw new IllegalStateException(errorMsg);
}
metricsRegistrar.registerCounter(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()).increment();
parsingApplicationParser.set(result.getAttributes().getApplicationParser());
LOG.info(PARSERS_UPDATE_COMPLETED);
} catch (Exception e) {
LOG.error(UPDATE_EXCEPTION_LOG, ExceptionUtils.getStackTrace(e));
return;
metricsRegistrar.registerCounter(SiembolMetrics.PARSING_CONFIGS_ERROR_UPDATE.getMetricName()).increment();
}
}
@@ -126,11 +141,37 @@ public class ParsingApplicationBolt extends BaseRichBolt {
byte[] log = (byte[])logObj;
ArrayList<ParsingApplicationResult> results = currentParser.parse(source, metadata, log);
if (!results.isEmpty()) {
KafkaWriterMessages kafkaWriterMessages = new KafkaWriterMessages();
results.forEach(x -> x.getMessages().forEach(y ->
kafkaWriterMessages.add(new KafkaWriterMessage(x.getTopic(), y))));
collector.emit(tuple, new Values(kafkaWriterMessages));
var kafkaWriterMessages = new KafkaWriterMessages();
var counters = new SiembolMetricsCounters();
for (var result : results) {
if (ParsingApplicationResult.ResultType.FILTERED.equals(result.getResultType())) {
metricsRegistrar.registerCounter(
SiembolMetrics.PARSING_SOURCE_TYPE_FILTERED_MESSAGES.getMetricName(result.getSourceType()))
.increment();
metricsRegistrar.registerCounter(SiembolMetrics.PARSING_APP_FILTERED_MESSAGES.getMetricName())
.increment();
} else {
results.forEach(x -> x.getMessages().forEach(y -> {
kafkaWriterMessages.add(new KafkaWriterMessage(x.getTopic(), y));
switch (result.getResultType()) {
case PARSED:
counters.add(SiembolMetrics.PARSING_SOURCE_TYPE_PARSED_MESSAGES
.getMetricName(result.getSourceType()));
counters.add(SiembolMetrics.PARSING_APP_PARSED_MESSAGES.getMetricName());
break;
case ERROR:
counters.add(SiembolMetrics.PARSING_APP_ERROR_MESSAGES
.getMetricName());
break;
}
}));
}
}
if (!kafkaWriterMessages.isEmpty()) {
collector.emit(tuple, new Values(kafkaWriterMessages, counters));
}
collector.ack(tuple);
@@ -138,6 +179,7 @@ public class ParsingApplicationBolt extends BaseRichBolt {
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(ParsingApplicationTuples.PARSING_MESSAGES.toString()));
declarer.declare(new Fields(ParsingApplicationTuples.PARSING_MESSAGES.toString(),
ParsingApplicationTuples.COUNTERS.toString()));
}
}

View File

@@ -4,7 +4,8 @@ public enum ParsingApplicationTuples {
SOURCE("source"),
METADATA("metadata"),
LOG("log"),
PARSING_MESSAGES("messages");
PARSING_MESSAGES("messages"),
COUNTERS("counters");
private final String name;
ParsingApplicationTuples(String name) {

View File

@@ -15,6 +15,8 @@ import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormParsingApplicationAttributesDto;
import uk.co.gresearch.siembol.common.storm.KafkaWriterBolt;
import uk.co.gresearch.siembol.common.model.StormAttributesDto;
@@ -85,7 +87,8 @@ public class StormParsingApplication {
public static StormTopology createTopology(StormParsingApplicationAttributesDto stormAppAttributes,
ParsingApplicationFactoryAttributes parsingAttributes,
ZooKeeperConnectorFactory zooKeeperConnectorFactory) throws Exception {
ZooKeeperConnectorFactory zooKeeperConnectorFactory,
StormMetricsRegistrarFactory metricsFactory) {
stormAppAttributes.getStormAttributes().getKafkaSpoutProperties().getRawMap()
.put(GROUP_ID_CONFIG, stormAppAttributes.getGroupId(parsingAttributes.getName()));
stormAppAttributes.getKafkaBatchWriterAttributes().getProducerProperties().getRawMap()
@@ -98,13 +101,15 @@ public class StormParsingApplication {
parsingAttributes.getInputParallelism());
builder.setBolt(parsingAttributes.getName(),
new ParsingApplicationBolt(stormAppAttributes, parsingAttributes, zooKeeperConnectorFactory),
new ParsingApplicationBolt(stormAppAttributes, parsingAttributes, zooKeeperConnectorFactory, metricsFactory),
parsingAttributes.getParsingParallelism())
.localOrShuffleGrouping(KAFKA_SPOUT);
builder.setBolt(KAFKA_WRITER,
new KafkaWriterBolt(stormAppAttributes.getKafkaBatchWriterAttributes(),
ParsingApplicationTuples.PARSING_MESSAGES.toString()),
ParsingApplicationTuples.PARSING_MESSAGES.toString(),
ParsingApplicationTuples.COUNTERS.toString(),
metricsFactory),
parsingAttributes.getOutputParallelism())
.localOrShuffleGrouping(parsingAttributes.getName());
@@ -132,7 +137,10 @@ public class StormParsingApplication {
ParsingApplicationFactoryAttributes parsingAttributes = result.getAttributes();
Config config = new Config();
config.putAll(stormAttributes.getStormAttributes().getStormConfig().getRawMap());
StormTopology topology = createTopology(stormAttributes, parsingAttributes, new ZooKeeperConnectorFactoryImpl());
StormTopology topology = createTopology(stormAttributes,
parsingAttributes,
new ZooKeeperConnectorFactoryImpl(),
new StormMetricsRegistrarFactoryImpl());
String topologyName = stormAttributes.getTopologyName(parsingAttributes.getName());
LOG.info(SUBMIT_INFO_LOG, topologyName, stormAttributesStr, parsingAttributesStr);
StormSubmitter.submitTopology(topologyName, config, topology);

View File

@@ -12,11 +12,13 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.StormMetricsTestRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormParsingApplicationAttributesDto;
import uk.co.gresearch.siembol.common.storm.KafkaWriterMessages;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.common.storm.SiembolMetricsCounters;
import uk.co.gresearch.siembol.common.testing.TestingZooKeeperConnectorFactory;
import uk.co.gresearch.siembol.parsers.application.factory.ParsingApplicationFactoryAttributes;
import java.io.IOException;
@@ -24,109 +26,142 @@ import java.util.ArrayList;
import java.util.Map;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
public class ParsingApplicationBoltTest {
private static ObjectReader JSON_READER = new ObjectMapper()
.readerFor(new TypeReference<Map<String, Object>>() {});
private static final ObjectReader JSON_READER = new ObjectMapper()
.readerFor(new TypeReference<Map<String, Object>>() {
});
String log = """
RAW_LOG
""";
RAW_LOG
""";
public static String metadata = """
{"is_metadata" : true}
""";
{"is_metadata" : true}
""";
public static String simpleSingleApplicationParser = """
{
"parsing_app_name": "test",
"parsing_app_version": 1,
"parsing_app_author": "dummy",
"parsing_app_description": "Description of parser application",
"parsing_app_settings": {
"input_topics": [
"secret"
],
"parse_metadata" : false,
"error_topic": "error",
"input_parallelism": 1,
"parsing_parallelism": 2,
"output_parallelism": 3,
"parsing_app_type": "single_parser"
},
"parsing_settings": {
"single_parser": {
"parser_name": "single",
"output_topic": "output"
}
}
}
""";
{
"parsing_app_name": "test",
"parsing_app_version": 1,
"parsing_app_author": "dummy",
"parsing_app_description": "Description of parser application",
"parsing_app_settings": {
"input_topics": [
"secret"
],
"parse_metadata" : false,
"error_topic": "error",
"input_parallelism": 1,
"parsing_parallelism": 2,
"output_parallelism": 3,
"parsing_app_type": "single_parser"
},
"parsing_settings": {
"single_parser": {
"parser_name": "single",
"output_topic": "output"
}
}
}
""";
public static String testParsersConfigs = """
{
"parsers_version": 1,
"parsers_configurations": [
{
"parser_description": "for testing single app parser",
"parser_version": 2,
"parser_name": "single",
"parser_author": "dummy",
"parser_attributes": {
"parser_type": "generic"
}
}
]
}
""";
{
"parsers_version": 1,
"parsers_configurations": [
{
"parser_description": "for testing single app parser",
"parser_version": 2,
"parser_name": "single",
"parser_author": "dummy",
"parser_attributes": {
"parser_type": "generic"
}
}
]
}
""";
public static String testParsersConfigsFiltered = """
{
"parsers_version": 2,
"parsers_configurations": [
{
"parser_description": "for testing single app parser",
"parser_version": 3,
"parser_name": "single",
"parser_author": "dummy",
"parser_attributes": {
"parser_type": "generic"
},
"transformations" : [
{
"transformation_type": "filter_message",
"attributes": {
"message_filter" : {
"matchers" : [
{
"field_name" : "original_string",
"pattern" : ".*",
"negated" : false
}]
}}}]
}
]
}
""";
private Tuple tuple;
private OutputCollector collector;
ParsingApplicationBolt parsingApplicationBolt;
ParsingApplicationFactoryAttributes parsingAttributes;
ZooKeeperAttributesDto zookeperAttributes;
StormParsingApplicationAttributesDto attributes;
ZooKeeperConnector zooKeeperConnector;
ZooKeeperConnectorFactory zooKeeperConnectorFactory;
ArgumentCaptor<Values> argumentEmitCaptor;
private ParsingApplicationBolt parsingApplicationBolt;
private ParsingApplicationFactoryAttributes parsingAttributes;
private ZooKeeperAttributesDto zooKeeperAttributes;
private final String parsersPath = "parsers";
private StormParsingApplicationAttributesDto attributes;
private TestingZooKeeperConnectorFactory zooKeeperConnectorFactory;
private ArgumentCaptor<Values> argumentEmitCaptor;
private StormMetricsTestRegistrarFactoryImpl metricsTestRegistrarFactory;
@Before
public void setUp() throws Exception {
public void setUp() {
parsingAttributes = new ParsingApplicationFactoryAttributes();
parsingAttributes.setApplicationParserSpecification(simpleSingleApplicationParser);
zookeperAttributes = new ZooKeeperAttributesDto();
zooKeeperAttributes = new ZooKeeperAttributesDto();
zooKeeperAttributes.setZkPath(parsersPath);
attributes = new StormParsingApplicationAttributesDto();
attributes.setZookeeperAttributes(zookeperAttributes);
attributes.setZookeeperAttributes(zooKeeperAttributes);
tuple = Mockito.mock(Tuple.class);
collector = Mockito.mock(OutputCollector.class);
argumentEmitCaptor = ArgumentCaptor.forClass(Values.class);
zooKeeperConnectorFactory = Mockito.mock(ZooKeeperConnectorFactory.class);
zooKeeperConnector = Mockito.mock(ZooKeeperConnector.class);
when(zooKeeperConnectorFactory.createZookeeperConnector(zookeperAttributes)).thenReturn(zooKeeperConnector);
when(zooKeeperConnector.getData()).thenReturn(testParsersConfigs);
zooKeeperConnectorFactory = new TestingZooKeeperConnectorFactory();
zooKeeperConnectorFactory.setData(parsersPath, testParsersConfigs);
when(tuple.getStringByField(eq(ParsingApplicationTuples.METADATA.toString()))).thenReturn(metadata);
when(tuple.getValueByField(eq(ParsingApplicationTuples.LOG.toString()))).thenReturn(log.trim().getBytes());
when(collector.emit(eq(tuple), argumentEmitCaptor.capture())).thenReturn(new ArrayList<>());
metricsTestRegistrarFactory = new StormMetricsTestRegistrarFactoryImpl();
parsingApplicationBolt = new ParsingApplicationBolt(attributes, parsingAttributes, zooKeeperConnectorFactory);
parsingApplicationBolt = new ParsingApplicationBolt(attributes,
parsingAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
parsingApplicationBolt.prepare(null, null, collector);
}
@Test
public void testMatchRule() throws IOException {
parsingApplicationBolt.execute(tuple);
public void testParsedOk() throws IOException {
parsingApplicationBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertEquals(1, messages.size());
@@ -136,6 +171,35 @@ public class ParsingApplicationBoltTest {
Assert.assertEquals("RAW_LOG", parsed.get(SiembolMessageFields.ORIGINAL.toString()));
Assert.assertEquals("single", parsed.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertNull(parsed.get("metadata_is_metadata"));
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counters = (SiembolMetricsCounters)values.get(1);
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_APP_PARSED_MESSAGES.getMetricName()));
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_SOURCE_TYPE_PARSED_MESSAGES
.getMetricName("single")));
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()));
}
@Test
public void testFilteredOk() throws Exception {
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()));
zooKeeperConnectorFactory.getZooKeeperConnector(parsersPath).setData(testParsersConfigsFiltered);
Assert.assertEquals(2,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()));
parsingApplicationBolt.execute(tuple);
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.PARSING_APP_FILTERED_MESSAGES.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.PARSING_SOURCE_TYPE_FILTERED_MESSAGES
.getMetricName("single")));
verify(collector, never()).emit(eq(tuple), argumentEmitCaptor.capture());
}
@Test
@@ -143,14 +207,17 @@ public class ParsingApplicationBoltTest {
parsingAttributes.setApplicationParserSpecification(simpleSingleApplicationParser.replace(
"\"parse_metadata\" : false", "\"parse_metadata\" : true"
));
parsingApplicationBolt = new ParsingApplicationBolt(attributes, parsingAttributes, zooKeeperConnectorFactory);
parsingApplicationBolt = new ParsingApplicationBolt(attributes,
parsingAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
parsingApplicationBolt.prepare(null, null, collector);
when(tuple.getStringByField(eq(ParsingApplicationTuples.METADATA.toString()))).thenReturn("INVALID");
parsingApplicationBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertEquals(1, messages.size());
@@ -160,6 +227,10 @@ public class ParsingApplicationBoltTest {
Assert.assertEquals("RAW_LOG", parsed.get("raw_message"));
Assert.assertEquals("error", parsed.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertEquals("parser_error", parsed.get("error_type"));
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counters = (SiembolMetricsCounters)values.get(1);
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_APP_ERROR_MESSAGES.getMetricName()));
}
@Test(expected = IllegalArgumentException.class)
@@ -174,12 +245,15 @@ public class ParsingApplicationBoltTest {
"\"parse_metadata\" : false", "\"parse_metadata\" : true"
));
parsingApplicationBolt = new ParsingApplicationBolt(attributes, parsingAttributes, zooKeeperConnectorFactory);
parsingApplicationBolt = new ParsingApplicationBolt(attributes,
parsingAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
parsingApplicationBolt.prepare(null, null, collector);
parsingApplicationBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(1, values.size());
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertEquals(1, messages.size());
@@ -189,12 +263,55 @@ public class ParsingApplicationBoltTest {
Assert.assertEquals("RAW_LOG", parsed.get(SiembolMessageFields.ORIGINAL.toString()));
Assert.assertEquals("single", parsed.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertEquals(true, parsed.get("metadata_is_metadata"));
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counters = (SiembolMetricsCounters)values.get(1);
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_APP_PARSED_MESSAGES.getMetricName()));
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_SOURCE_TYPE_PARSED_MESSAGES
.getMetricName("single")));
}
@Test(expected = IllegalStateException.class)
public void testExceptionData() throws Exception {
when(zooKeeperConnector.getData()).thenReturn("INVALID");
parsingApplicationBolt = new ParsingApplicationBolt(attributes, parsingAttributes, zooKeeperConnectorFactory);
public void testWrongParserconfigInit() {
zooKeeperConnectorFactory = new TestingZooKeeperConnectorFactory();
zooKeeperConnectorFactory.setData(parsersPath, "INVALID");
parsingApplicationBolt = new ParsingApplicationBolt(attributes,
parsingAttributes,
zooKeeperConnectorFactory,
metricsTestRegistrarFactory);
parsingApplicationBolt.prepare(null, null, collector);
}
@Test
public void testWrongParserconfigUpdate() throws Exception {
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()));
zooKeeperConnectorFactory.getZooKeeperConnector(parsersPath).setData("INVALID");
Assert.assertEquals(1,
metricsTestRegistrarFactory.getCounterValue(SiembolMetrics.PARSING_CONFIGS_UPDATE.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrarFactory
.getCounterValue(SiembolMetrics.PARSING_CONFIGS_ERROR_UPDATE.getMetricName()));
parsingApplicationBolt.execute(tuple);
Values values = argumentEmitCaptor.getValue();
Assert.assertNotNull(values);
Assert.assertEquals(2, values.size());
Assert.assertTrue(values.get(0) instanceof KafkaWriterMessages);
KafkaWriterMessages messages = (KafkaWriterMessages)values.get(0);
Assert.assertEquals(1, messages.size());
Assert.assertEquals("output", messages.get(0).getTopic());
Map<String, Object> parsed = JSON_READER.readValue(messages.get(0).getMessage());
Assert.assertEquals("RAW_LOG", parsed.get(SiembolMessageFields.ORIGINAL.toString()));
Assert.assertEquals("single", parsed.get(SiembolMessageFields.SENSOR_TYPE.toString()));
Assert.assertNull(parsed.get("metadata_is_metadata"));
Assert.assertTrue(values.get(1) instanceof SiembolMetricsCounters);
var counters = (SiembolMetricsCounters)values.get(1);
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_APP_PARSED_MESSAGES.getMetricName()));
Assert.assertTrue(counters.contains(SiembolMetrics.PARSING_SOURCE_TYPE_PARSED_MESSAGES
.getMetricName("single")));
}
}

View File

@@ -10,6 +10,7 @@ import org.apache.storm.generated.StormTopology;
import org.junit.*;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.constants.SiembolMessageFields;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactoryImpl;
import uk.co.gresearch.siembol.common.model.StormParsingApplicationAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
@@ -140,7 +141,8 @@ public class StormParsingApplicationTest {
kafkaRule.waitForStartup();
topology = StormParsingApplication.createTopology(stormAttributes,
parsingAttributes,
zooKeeperConnectorFactory);
zooKeeperConnectorFactory,
new StormMetricsRegistrarFactoryImpl());
LocalCluster cluster = new LocalCluster();
Config config = new Config();

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<modules>
<module>parsing-core</module>

View File

@@ -6,7 +6,7 @@
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<name>siembol</name>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<description>A scalable, advanced security analytics framework based on open-source big data technologies.</description>
<inceptionYear>2019</inceptionYear>
<url>https://siembol.io/</url>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<modules>
<module>responding-core</module>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>responding</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -35,12 +35,12 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>alerting-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>

View File

@@ -1,9 +0,0 @@
package uk.co.gresearch.siembol.response.common;
public class InactiveMetricFactory implements MetricFactory {
private final MetricCounter inactiveCounter = () -> {};
@Override
public MetricCounter createCounter(String name, String description) {
return inactiveCounter;
}
}

View File

@@ -1,5 +0,0 @@
package uk.co.gresearch.siembol.response.common;
public interface MetricCounter {
void increment();
}

View File

@@ -1,5 +0,0 @@
package uk.co.gresearch.siembol.response.common;
public interface MetricFactory {
MetricCounter createCounter(String name, String description);
}

View File

@@ -1,30 +0,0 @@
package uk.co.gresearch.siembol.response.common;
public enum MetricNames {
RULE_MATCHES("response_rule_matches", "Number of matches of the rule"),
RULE_ERROR_MATCHES("response_rule_error_matches", "Number of error matches of the rule"),
RULE_FILTERS("response_rule_filters", "Number of messages filtered by the rule"),
ENGINE_PROCESSED_MESSAGES("response_engine_processed_alerts", "Number of messages processed by response engine"),
ENGINE_FILTERED_MESSAGES("response_engine_filtered_alerts", "Number of messages filtered by response engine"),
ENGINE_ERROR_MESSAGES("response_engine_errors", "Number of messages with error result by response engine"),
ENGINE_NO_MATCH_MESSAGES("response_engine_no_matches", "Number of messages with not match result by response engine");
private final String name;
private final String description;
MetricNames(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getNameWithSuffix(String suffix) {
return String.format("%s_%s", name, suffix);
}
}

View File

@@ -1,5 +1,7 @@
package uk.co.gresearch.siembol.response.common;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
/**
* Responding evaluator factory
* - creates evaluator instances
@@ -43,11 +45,11 @@ public interface RespondingEvaluatorFactory {
}
/**
* Register metric factory that can be used for creating metrics
* Register metric factory that can be used for registering metrics
*
* @return RespondingResult with OK status code on success or ERROR status code with message otherwise
*/
default RespondingResult registerMetrics(MetricFactory metricFactory) {
default RespondingResult registerMetrics(SiembolMetricsRegistrar metricRegistrar) {
return new RespondingResult(RespondingResult.StatusCode.OK, new RespondingResultAttributes());
}
}

View File

@@ -1,29 +0,0 @@
package uk.co.gresearch.siembol.response.common;
public class TestMetricCounter implements MetricCounter {
private int counter = 0;
private final String name;
private final String description;
public TestMetricCounter(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
@Override
public void increment() {
counter++;
}
public int getValue() {
return counter;
}
}

View File

@@ -1,19 +0,0 @@
package uk.co.gresearch.siembol.response.common;
import java.util.HashMap;
import java.util.Map;
public class TestMetricFactory implements MetricFactory {
private final Map<String, TestMetricCounter> counters = new HashMap<>();
@Override
public MetricCounter createCounter(String name, String description) {
TestMetricCounter newCounter = new TestMetricCounter(name, description);
counters.put(name, newCounter);
return newCounter;
}
public TestMetricCounter getCounter(String name) {
return counters.get(name);
}
}

View File

@@ -7,6 +7,7 @@ import uk.co.gresearch.siembol.common.jsonschema.JsonSchemaValidator;
import uk.co.gresearch.siembol.common.jsonschema.SiembolJsonSchemaValidator;
import uk.co.gresearch.siembol.common.jsonschema.UnionJsonType;
import uk.co.gresearch.siembol.common.jsonschema.UnionJsonTypeOption;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.result.SiembolResult;
import uk.co.gresearch.siembol.common.testing.StringTestingLogger;
import uk.co.gresearch.siembol.common.testing.TestingLogger;
@@ -41,20 +42,20 @@ public class RespondingCompilerImpl implements RespondingCompiler {
private final String rulesJsonSchemaStr;
private final JsonSchemaValidator rulesSchemaValidator;
private final JsonSchemaValidator testSpecificationValidator;
private final MetricFactory metricFactory;
private final SiembolMetricsRegistrar metricsRegistrar;
public RespondingCompilerImpl(Builder builder) {
this.respondingEvaluatorFactoriesMap = builder.respondingEvaluatorFactoriesMap;
this.rulesJsonSchemaStr = builder.rulesJsonSchemaStr;
this.rulesSchemaValidator = builder.rulesSchemaValidator;
this.metricFactory = builder.metricFactory;
this.metricsRegistrar = builder.metricsRegistrar;
this.testSpecificationValidator = builder.testSpecificationValidator;
}
private ResponseRule createResponseRule(RuleDto ruleDto, TestingLogger logger) {
ResponseRule.Builder builder = new ResponseRule.Builder();
builder
.metricFactory(metricFactory)
.metricsRegistrar(metricsRegistrar)
.logger(logger)
.ruleName(ruleDto.getRuleName())
.ruleVersion(ruleDto.getRuleVersion());
@@ -97,7 +98,7 @@ public class RespondingCompilerImpl implements RespondingCompiler {
ResponseEngine responseEngine = new RulesEngine.Builder()
.metadata(metadataAttributes)
.rules(responseRules)
.metricFactory(metricFactory)
.metricsRegistrar(metricsRegistrar)
.testingLogger(logger)
.build();
@@ -221,10 +222,10 @@ public class RespondingCompilerImpl implements RespondingCompiler {
private String rulesJsonSchemaStr;
private JsonSchemaValidator rulesSchemaValidator;
private JsonSchemaValidator testSpecificationValidator;
private MetricFactory metricFactory;
private SiembolMetricsRegistrar metricsRegistrar;
public Builder metricFactory(MetricFactory metricFactory) {
this.metricFactory = metricFactory;
public Builder metricsRegistrar(SiembolMetricsRegistrar metricsRegistrar) {
this.metricsRegistrar = metricsRegistrar;
return this;
}
@@ -250,7 +251,7 @@ public class RespondingCompilerImpl implements RespondingCompiler {
testSpecificationValidator = new SiembolJsonSchemaValidator(ResponseTestSpecificationDto.class);
respondingEvaluatorFactoriesMap.forEach((k, v) -> {
v.registerMetrics(metricFactory);
v.registerMetrics(metricsRegistrar);
});
List<UnionJsonTypeOption> evaluatorOptions = respondingEvaluatorFactoriesMap.keySet().stream()

View File

@@ -2,6 +2,9 @@ package uk.co.gresearch.siembol.response.engine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.testing.InactiveTestingLogger;
import uk.co.gresearch.siembol.common.testing.TestingLogger;
import uk.co.gresearch.siembol.response.common.*;
@@ -19,9 +22,9 @@ public class ResponseRule implements Evaluable {
private final String ruleName;
private final String fullRuleName;
private final List<Evaluable> evaluators;
private final MetricCounter matchesCounter;
private final MetricCounter filtersCounter;
private final MetricCounter errorsCounter;
private final SiembolCounter matchesCounter;
private final SiembolCounter filtersCounter;
private final SiembolCounter errorsCounter;
private final TestingLogger logger;
private ResponseRule(Builder builder) {
@@ -82,15 +85,15 @@ public class ResponseRule implements Evaluable {
private String ruleName;
private String fullRuleName;
private Integer ruleVersion;
private MetricFactory metricFactory;
private MetricCounter matchesCounter;
private MetricCounter filtersCounter;
private MetricCounter errorsCounter;
private SiembolMetricsRegistrar metricsRegistrar;
private SiembolCounter matchesCounter;
private SiembolCounter filtersCounter;
private SiembolCounter errorsCounter;
private List<Evaluable> evaluators = new ArrayList<>();
private TestingLogger logger = new InactiveTestingLogger();
public Builder metricFactory(MetricFactory metricFactory) {
this.metricFactory = metricFactory;
public Builder metricsRegistrar(SiembolMetricsRegistrar metricsRegistrar) {
this.metricsRegistrar = metricsRegistrar;
return this;
}
@@ -117,22 +120,19 @@ public class ResponseRule implements Evaluable {
public ResponseRule build() {
if (ruleName == null
|| ruleVersion == null
|| metricFactory == null) {
|| metricsRegistrar == null) {
throw new IllegalArgumentException(MISSING_ATTRIBUTES);
}
fullRuleName = String.format(FULL_RULE_NAME_FORMAT_MSG, ruleName, ruleVersion);
this.matchesCounter = metricFactory.createCounter(
MetricNames.RULE_MATCHES.getNameWithSuffix(ruleName),
MetricNames.RULE_MATCHES.getDescription());
this.matchesCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_RULE_MATCHES.getMetricName(ruleName));
this.filtersCounter = metricFactory.createCounter(
MetricNames.RULE_FILTERS.getNameWithSuffix(ruleName),
MetricNames.RULE_FILTERS.getDescription());
this.filtersCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_RULE_FILTERED_ALERTS.getMetricName(ruleName));
this.errorsCounter = metricFactory.createCounter(
MetricNames.RULE_ERROR_MATCHES.getNameWithSuffix(ruleName),
MetricNames.RULE_ERROR_MATCHES.getDescription());
this.errorsCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_RULE_ERROR_MATCHES.getMetricName(ruleName));
return new ResponseRule(this);
}

View File

@@ -1,5 +1,8 @@
package uk.co.gresearch.siembol.response.engine;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.testing.InactiveTestingLogger;
import uk.co.gresearch.siembol.common.testing.TestingLogger;
import uk.co.gresearch.siembol.response.common.*;
@@ -13,10 +16,10 @@ public class RulesEngine implements ResponseEngine {
private static final String NO_RULE_MATCHES_THE_ALERT = "No rule matches the alert %s";
private final List<? extends Evaluable> rules;
private final MetricCounter messagesCounter;
private final MetricCounter filtersCounter;
private final MetricCounter errorsCounter;
private final MetricCounter noMatchesCounter;
private final SiembolCounter messagesCounter;
private final SiembolCounter filtersCounter;
private final SiembolCounter errorsCounter;
private final SiembolCounter noMatchesCounter;
private final TestingLogger logger;
private final RespondingResultAttributes metadataAttributes;
@@ -68,15 +71,15 @@ public class RulesEngine implements ResponseEngine {
public static class Builder {
private List<? extends Evaluable> rules;
private TestingLogger logger = new InactiveTestingLogger();
private MetricFactory metricFactory;
private MetricCounter messagesCounter;
private MetricCounter filtersCounter;
private MetricCounter errorsCounter;
private MetricCounter noMatchesCounter;
private SiembolMetricsRegistrar metricsRegistrar;
private SiembolCounter messagesCounter;
private SiembolCounter filtersCounter;
private SiembolCounter errorsCounter;
private SiembolCounter noMatchesCounter;
private RespondingResultAttributes metadataAttributes;
public Builder metricFactory(MetricFactory metricFactory) {
this.metricFactory = metricFactory;
public Builder metricsRegistrar(SiembolMetricsRegistrar metricsRegistrar) {
this.metricsRegistrar = metricsRegistrar;
return this;
}
@@ -97,19 +100,19 @@ public class RulesEngine implements ResponseEngine {
public RulesEngine build() {
if (rules == null || rules.isEmpty()
|| metricFactory == null
|| metricsRegistrar == null
|| metadataAttributes == null) {
throw new IllegalArgumentException(MISSING_ATTRIBUTES);
}
messagesCounter = metricFactory.createCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName(),
MetricNames.ENGINE_PROCESSED_MESSAGES.getDescription());
filtersCounter = metricFactory.createCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName(),
MetricNames.ENGINE_FILTERED_MESSAGES.getDescription());
errorsCounter = metricFactory.createCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName(),
MetricNames.ENGINE_ERROR_MESSAGES.getDescription());
noMatchesCounter = metricFactory.createCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName(),
MetricNames.ENGINE_NO_MATCH_MESSAGES.getDescription());
messagesCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName());
filtersCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName());
errorsCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName());
noMatchesCounter = metricsRegistrar
.registerCounter(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName());
return new RulesEngine(this);
}

View File

@@ -4,6 +4,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.metrics.test.SiembolMetricsTestRegistrar;
import uk.co.gresearch.siembol.response.common.*;
import uk.co.gresearch.siembol.response.evaluators.fixed.FixedResultEvaluator;
@@ -119,7 +120,8 @@ public class RespondingCompilerImplTest {
private RespondingCompilerImpl compiler;
private RespondingCompilerImpl.Builder builder;
private MetricFactory metricFactory;
private SiembolMetricsTestRegistrar metricsTestRegistrar;
private RespondingEvaluatorFactory evaluatorFactory;
private RespondingResult evaluatorSchemaResult;
private RespondingResult evaluatorTypeResult;
@@ -132,9 +134,9 @@ public class RespondingCompilerImplTest {
@Before
public void setUp() throws Exception {
metricFactory = new TestMetricFactory();
metricsTestRegistrar = new SiembolMetricsTestRegistrar();
builder = new RespondingCompilerImpl.Builder()
.metricFactory(metricFactory);
.metricsRegistrar(metricsTestRegistrar);
evaluatorTypeResult = RespondingResult.fromEvaluatorType("b_first_evaluator");
evaluatorNextTypeResult = RespondingResult.fromEvaluatorType("a_second_evaluator");

View File

@@ -4,6 +4,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.SiembolMetricsTestRegistrar;
import uk.co.gresearch.siembol.response.common.*;
import uk.co.gresearch.siembol.response.evaluators.fixed.FixedResultEvaluator;
@@ -20,18 +22,18 @@ public class ResponseRuleTest {
private final int ruleVerion = 1;
private final String fullRuleName = "Test_rule_v1";
private final String metchesMetricName = MetricNames.RULE_MATCHES.getNameWithSuffix(ruleName);
private final String errorMetricName = MetricNames.RULE_ERROR_MATCHES.getNameWithSuffix(ruleName);
private final String filteredMetricName = MetricNames.RULE_FILTERS.getNameWithSuffix(ruleName);
private final String metchesMetricName = SiembolMetrics.RESPONSE_RULE_MATCHES.getMetricName(ruleName);
private final String errorMetricName = SiembolMetrics.RESPONSE_RULE_ERROR_MATCHES.getMetricName(ruleName);
private final String filteredMetricName = SiembolMetrics.RESPONSE_RULE_FILTERED_ALERTS.getMetricName(ruleName);
private ResponseAlert alert;
Evaluable evaluator;
Evaluable evaluatorNext;
ResponseRule.Builder builder;
ResponseRule rule;
TestMetricFactory metricFactory;
RespondingResult evaluatorResult;
RespondingResultAttributes resultAttributes;
private Evaluable evaluator;
private Evaluable evaluatorNext;
private ResponseRule.Builder builder;
private ResponseRule rule;
private SiembolMetricsTestRegistrar metricsTestRegistrar;
private RespondingResult evaluatorResult;
private RespondingResultAttributes resultAttributes;
@Before
public void setUp() {
@@ -45,9 +47,9 @@ public class ResponseRuleTest {
evaluator = Mockito.mock(Evaluable.class);
when(evaluator.evaluate(alert)).thenReturn(evaluatorResult);
metricFactory = new TestMetricFactory();
metricsTestRegistrar = new SiembolMetricsTestRegistrar();
builder = new ResponseRule.Builder()
.metricFactory(metricFactory)
.metricsRegistrar(metricsTestRegistrar.cachedRegistrar())
.ruleName(ruleName)
.ruleVersion(ruleVerion);
@@ -63,9 +65,9 @@ public class ResponseRuleTest {
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(NO_MATCH, result.getAttributes().getResult());
Assert.assertEquals(2, result.getAttributes().getAlert().size());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -83,9 +85,9 @@ public class ResponseRuleTest {
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(NO_MATCH, result.getAttributes().getResult());
Assert.assertEquals(2, result.getAttributes().getAlert().size());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -101,9 +103,9 @@ public class ResponseRuleTest {
.get(ResponseFields.FULL_RULE_NAME.toString()));
Assert.assertEquals(ruleName, result.getAttributes().getAlert().get(ResponseFields.RULE_NAME.toString()));
Assert.assertEquals(1, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -121,9 +123,9 @@ public class ResponseRuleTest {
.get(ResponseFields.FULL_RULE_NAME.toString()));
Assert.assertEquals(ruleName, result.getAttributes().getAlert().get(ResponseFields.RULE_NAME.toString()));
Assert.assertEquals(1, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -140,9 +142,9 @@ public class ResponseRuleTest {
.get(ResponseFields.FULL_RULE_NAME.toString()));
Assert.assertEquals(ruleName, result.getAttributes().getAlert().get(ResponseFields.RULE_NAME.toString()));
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -159,9 +161,9 @@ public class ResponseRuleTest {
Assert.assertEquals(fullRuleName, result.getAttributes().getAlert()
.get(ResponseFields.FULL_RULE_NAME.toString()));
Assert.assertEquals(ruleName, result.getAttributes().getAlert().get(ResponseFields.RULE_NAME.toString()));
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -174,9 +176,9 @@ public class ResponseRuleTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -191,9 +193,9 @@ public class ResponseRuleTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@@ -207,9 +209,9 @@ public class ResponseRuleTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test
@@ -224,9 +226,9 @@ public class ResponseRuleTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(0, metricFactory.getCounter(metchesMetricName).getValue());
Assert.assertEquals(1, metricFactory.getCounter(errorMetricName).getValue());
Assert.assertEquals(0, metricFactory.getCounter(filteredMetricName).getValue());
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(metchesMetricName));
Assert.assertEquals(1, metricsTestRegistrar.getCounterValue(errorMetricName));
Assert.assertEquals(0, metricsTestRegistrar.getCounterValue(filteredMetricName));
}
@Test(expected = IllegalArgumentException.class)

View File

@@ -4,6 +4,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.test.SiembolMetricsTestRegistrar;
import uk.co.gresearch.siembol.response.common.*;
import java.util.Arrays;
@@ -18,17 +20,17 @@ import static uk.co.gresearch.siembol.response.common.ResponseEvaluationResult.N
public class RulesEngineTest {
private ResponseAlert alert;
Evaluable rule;
Evaluable ruleNext;
List<Evaluable> rules;
RulesEngine.Builder builder;
TestMetricFactory metricFactory;
RespondingResult ruleResult;
RespondingResultAttributes resultAttributes;
RespondingResultAttributes metadataAttributes;
RespondingResult ruleNextResult;
RespondingResultAttributes resultNextAttributes;
RulesEngine engine;
private Evaluable rule;
private Evaluable ruleNext;
private List<Evaluable> rules;
private RulesEngine.Builder builder;
private SiembolMetricsTestRegistrar metricsTestRegistrar;
private RespondingResult ruleResult;
private RespondingResultAttributes resultAttributes;
private RespondingResultAttributes metadataAttributes;
private RespondingResult ruleNextResult;
private RespondingResultAttributes resultNextAttributes;
private RulesEngine engine;
@Before
public void setUp() {
@@ -50,9 +52,9 @@ public class RulesEngineTest {
rules = Arrays.asList(rule, ruleNext);
metadataAttributes = new RespondingResultAttributes();
metricFactory = new TestMetricFactory();
metricsTestRegistrar = new SiembolMetricsTestRegistrar();
builder = new RulesEngine.Builder()
.metricFactory(metricFactory)
.metricsRegistrar(metricsTestRegistrar.cachedRegistrar())
.metadata(metadataAttributes)
.rules(rules);
@@ -69,14 +71,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.OK, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(MATCH, result.getAttributes().getResult());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -92,14 +94,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.OK, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(MATCH, result.getAttributes().getResult());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -114,14 +116,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.OK, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(FILTERED, result.getAttributes().getResult());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -137,14 +139,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.OK, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(FILTERED, result.getAttributes().getResult());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -159,14 +161,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -182,14 +184,14 @@ public class RulesEngineTest {
Assert.assertEquals(RespondingResult.StatusCode.ERROR, result.getStatusCode());
Assert.assertNotNull(result.getAttributes());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}
@@ -206,14 +208,14 @@ public class RulesEngineTest {
Assert.assertNotNull(result.getAttributes());
Assert.assertEquals(NO_MATCH, result.getAttributes().getResult());
Assert.assertNotNull(result.getAttributes().getMessage());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_PROCESSED_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricFactory
.getCounter(MetricNames.ENGINE_NO_MATCH_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_ERROR_MESSAGES.getName()).getValue());
Assert.assertEquals(0, metricFactory
.getCounter(MetricNames.ENGINE_FILTERED_MESSAGES.getName()).getValue());
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_PROCESSED_ALERTS.getMetricName()));
Assert.assertEquals(1, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_NO_MATCHES.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_ERRORS.getMetricName()));
Assert.assertEquals(0, metricsTestRegistrar
.getCounterValue(SiembolMetrics.RESPONSE_ENGINE_FILTERED_ALERTS.getMetricName()));
Assert.assertEquals(RespondingResult.StatusCode.OK, engine.getRulesMetadata().getStatusCode());
Assert.assertEquals(metadataAttributes, engine.getRulesMetadata().getAttributes());
}

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>responding</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencyManagement>
<dependencies>
@@ -51,7 +51,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol-common</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -62,7 +62,7 @@
<dependency>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>responding-core</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>

View File

@@ -1,18 +0,0 @@
package uk.co.gresearch.siembol.response.stream.rest;
import io.micrometer.core.instrument.Counter;
import uk.co.gresearch.siembol.response.common.MetricCounter;
public class ResponseCounter implements MetricCounter {
private final Counter counter;
public ResponseCounter(Counter counter) {
this.counter = counter;
}
@Override
public void increment() {
counter.increment();
}
}

View File

@@ -1,23 +0,0 @@
package uk.co.gresearch.siembol.response.stream.rest;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uk.co.gresearch.siembol.response.common.MetricCounter;
import uk.co.gresearch.siembol.response.common.MetricFactory;
@Service
public class ResponseMetricFactory implements MetricFactory {
@Autowired
private final MeterRegistry registry;
public ResponseMetricFactory(MeterRegistry registry) {
this.registry = registry;
}
@Override
public MetricCounter createCounter(String name, String description) {
return new ResponseCounter(Counter.builder(name).description(description).register(registry));
}
}

View File

@@ -1,18 +1,22 @@
package uk.co.gresearch.siembol.response.stream.rest.application;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.plugin.core.OrderAwarePluginRegistry;
import org.springframework.plugin.core.config.EnablePluginRegistries;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.spring.SpringMetricsRegistrar;
import uk.co.gresearch.siembol.response.common.ProvidedEvaluators;
import uk.co.gresearch.siembol.response.common.RespondingEvaluatorFactory;
import uk.co.gresearch.siembol.response.common.ResponsePlugin;
import uk.co.gresearch.siembol.response.compiler.RespondingCompiler;
import uk.co.gresearch.siembol.response.compiler.RespondingCompilerImpl;
import uk.co.gresearch.siembol.response.stream.rest.ResponseMetricFactory;
import uk.co.gresearch.siembol.response.stream.ruleservice.*;
import java.util.ArrayList;
@@ -24,17 +28,22 @@ public class ApplicationConfiguration implements DisposableBean {
@Autowired
private ResponseConfigurationProperties properties;
@Autowired
private ResponseMetricFactory counterFactory;
private MeterRegistry springMeterRegistrar;
@Autowired
@Qualifier("responsePluginRegistry")
private OrderAwarePluginRegistry<ResponsePlugin, String> pluginRegistry;
private RespondingCompiler respondingCompiler;
private RulesService streamService;
private RulesProvider rulesProvider;
@Bean
RespondingCompiler respondingCompiler() throws Exception {
@Bean("metricsRegistrar")
SiembolMetricsRegistrar metricsRegistrar() {
return new SpringMetricsRegistrar(springMeterRegistrar);
}
@Bean("respondingCompiler")
@DependsOn("metricsRegistrar")
RespondingCompiler respondingCompiler(@Autowired SiembolMetricsRegistrar metricsRegistrar) throws Exception {
List<RespondingEvaluatorFactory> evaluatorFactories = new ArrayList<>();
evaluatorFactories.addAll(ProvidedEvaluators.getRespondingEvaluatorFactories(properties.getEvaluatorsProperties())
.getAttributes()
@@ -48,27 +57,28 @@ public class ApplicationConfiguration implements DisposableBean {
return new RespondingCompilerImpl.Builder()
.addRespondingEvaluatorFactories(evaluatorFactories)
.metricFactory(counterFactory)
.metricsRegistrar(metricsRegistrar)
.build();
}
@Bean
RulesService centrifugeService() throws Exception {
respondingCompiler = respondingCompiler();
rulesProvider = rulesProvider();
@DependsOn({"rulesProvider", "respondingCompiler"})
RulesService centrifugeService(@Autowired RespondingCompiler respondingCompiler,
@Autowired RulesProvider rulesProvider) {
streamService = properties.getInactiveStreamService()
? new InactiveRulesService()
: new KafkaStreamRulesService(rulesProvider, properties);
return streamService;
}
@Bean
RulesProvider rulesProvider() throws Exception {
rulesProvider = properties.getInactiveStreamService()
@Bean("rulesProvider")
@DependsOn({"respondingCompiler", "metricsRegistrar"})
RulesProvider rulesProvider(
@Autowired RespondingCompiler respondingCompiler,
@Autowired SiembolMetricsRegistrar metricsRegistrar) throws Exception {
return properties.getInactiveStreamService()
? () -> null :
new ZooKeeperRulesProvider(properties.getZookeperAttributes(), respondingCompiler);
return rulesProvider;
new ZooKeeperRulesProvider(properties.getZookeperAttributes(), respondingCompiler, metricsRegistrar);
}
@Override

View File

@@ -5,6 +5,9 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.constants.SiembolConstants;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
@@ -31,18 +34,24 @@ public class ZooKeeperRulesProvider implements RulesProvider {
private final AtomicReference<ResponseEngine> currentEngine = new AtomicReference<>();
private final ZooKeeperConnector zooKeeperConnector;
private final RespondingCompiler respondingCompiler;
private final SiembolCounter updateCounter;
private final SiembolCounter updateErrorCounter;
public ZooKeeperRulesProvider(ZooKeeperAttributesDto zookeperAttributes,
RespondingCompiler respondingCompiler) throws Exception {
this(new ZooKeeperConnectorFactoryImpl(), zookeperAttributes, respondingCompiler);
RespondingCompiler respondingCompiler,
SiembolMetricsRegistrar metricsRegistrar) throws Exception {
this(new ZooKeeperConnectorFactoryImpl(), zookeperAttributes, respondingCompiler, metricsRegistrar);
}
ZooKeeperRulesProvider(ZooKeeperConnectorFactory factory,
ZooKeeperAttributesDto zookeperAttributes,
RespondingCompiler respondingCompiler) throws Exception {
RespondingCompiler respondingCompiler,
SiembolMetricsRegistrar metricsRegistrar) throws Exception {
LOG.info(INIT_START);
this.updateCounter = metricsRegistrar.registerCounter(SiembolMetrics.RESPONSE_RULES_UPDATE.getMetricName());
this.updateErrorCounter = metricsRegistrar.registerCounter(SiembolMetrics.RESPONSE_RULES_ERROR_UPDATE.getMetricName());
this.respondingCompiler = respondingCompiler;
zooKeeperConnector = factory.createZookeeperConnector(zookeperAttributes);
@@ -61,13 +70,16 @@ public class ZooKeeperRulesProvider implements RulesProvider {
LOG.info(UPDATE_TRY_MSG_FORMAT, StringUtils.left(jsonRules, SiembolConstants.MAX_SIZE_CONFIG_UPDATE_LOG));
RespondingResult result = respondingCompiler.compile(jsonRules);
if (result.getStatusCode() != RespondingResult.StatusCode.OK) {
updateErrorCounter.increment();
LOG.error(COMPILE_RULES_ERROR_MSG_FORMAT, result.getAttributes().getMessage());
return;
}
currentEngine.set(result.getAttributes().getResponseEngine());
updateCounter.increment();
LOG.info(PARSERS_UPDATE_COMPLETED);
} catch (Exception e) {
updateErrorCounter.increment();
LOG.error(UPDATE_EXCEPTION_LOG, ExceptionUtils.getStackTrace(e));
}
}

View File

@@ -3,7 +3,11 @@ package uk.co.gresearch.siembol.response.stream.ruleservice;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import uk.co.gresearch.siembol.common.metrics.SiembolMetrics;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.test.SiembolMetricsTestRegistrar;
import uk.co.gresearch.siembol.common.model.ZooKeeperAttributesDto;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnector;
import uk.co.gresearch.siembol.common.zookeeper.ZooKeeperConnectorFactory;
@@ -16,8 +20,8 @@ import uk.co.gresearch.siembol.response.model.ProvidedEvaluatorsProperties;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static uk.co.gresearch.siembol.response.common.RespondingResult.StatusCode.OK;
import static uk.co.gresearch.siembol.response.common.ResponseEvaluationResult.MATCH;
@@ -45,15 +49,18 @@ public class ZooKeeperRulesProviderTest {
""";
private RespondingCompiler compiler;
private MetricFactory testMetricFactory;
private SiembolMetricsTestRegistrar metricsTestRegistrar;
private SiembolMetricsRegistrar cachedMetricsRegistrar;
private ZooKeeperConnectorFactory zooKeeperConnectorFactory;
private ZooKeeperConnector rulesZooKeeperConnector;
private ArgumentCaptor<Runnable> zooKeeperCallback;
private ZooKeeperRulesProvider rulesProvider;
private ZooKeeperAttributesDto zooKeeperAttributes;
@Before
public void setUp() throws Exception {
testMetricFactory = new TestMetricFactory();
metricsTestRegistrar = new SiembolMetricsTestRegistrar();
cachedMetricsRegistrar = metricsTestRegistrar.cachedRegistrar();
List<RespondingEvaluatorFactory> evaluatorFactories = new ArrayList<>(
ProvidedEvaluators.getRespondingEvaluatorFactories(new ProvidedEvaluatorsProperties())
.getAttributes()
@@ -61,7 +68,7 @@ public class ZooKeeperRulesProviderTest {
compiler = new RespondingCompilerImpl.Builder()
.addRespondingEvaluatorFactories(evaluatorFactories)
.metricFactory(testMetricFactory)
.metricsRegistrar(cachedMetricsRegistrar)
.build();
@@ -72,7 +79,15 @@ public class ZooKeeperRulesProviderTest {
when(zooKeeperConnectorFactory.createZookeeperConnector(zooKeeperAttributes))
.thenReturn(rulesZooKeeperConnector);
when(rulesZooKeeperConnector.getData()).thenReturn(testingRules);
rulesProvider = new ZooKeeperRulesProvider(zooKeeperConnectorFactory, zooKeeperAttributes, compiler);
zooKeeperCallback = ArgumentCaptor.forClass(Runnable.class);
doNothing().when(rulesZooKeeperConnector).addCacheListener(zooKeeperCallback.capture());
rulesProvider = new ZooKeeperRulesProvider(zooKeeperConnectorFactory,
zooKeeperAttributes,
compiler,
cachedMetricsRegistrar);
Assert.assertEquals(1,
metricsTestRegistrar.getCounterValue(SiembolMetrics.RESPONSE_RULES_UPDATE.getMetricName()));
}
@@ -89,7 +104,10 @@ public class ZooKeeperRulesProviderTest {
@Test(expected = java.lang.IllegalStateException.class)
public void testInvalidRulesInit() throws Exception {
when(rulesZooKeeperConnector.getData()).thenReturn("INVALID");
rulesProvider = new ZooKeeperRulesProvider(zooKeeperConnectorFactory, zooKeeperAttributes, compiler);
rulesProvider = new ZooKeeperRulesProvider(zooKeeperConnectorFactory,
zooKeeperAttributes,
compiler,
cachedMetricsRegistrar);
}
@Test
@@ -99,4 +117,27 @@ public class ZooKeeperRulesProviderTest {
Assert.assertEquals(OK, result.getStatusCode());
Assert.assertEquals(MATCH, result.getAttributes().getResult());
}
@Test
public void updateOk() {
zooKeeperCallback.getValue().run();
Assert.assertEquals(2,
metricsTestRegistrar.getCounterValue(SiembolMetrics.RESPONSE_RULES_UPDATE.getMetricName()));
zooKeeperCallback.getValue().run();
Assert.assertEquals(3,
metricsTestRegistrar.getCounterValue(SiembolMetrics.RESPONSE_RULES_UPDATE.getMetricName()));
verify(rulesZooKeeperConnector, times(3)).getData();
}
@Test
public void updateError() {
when(rulesZooKeeperConnector.getData()).thenReturn("INVALID");
zooKeeperCallback.getValue().run();
Assert.assertEquals(1,
metricsTestRegistrar.getCounterValue(SiembolMetrics.RESPONSE_RULES_UPDATE.getMetricName()));
Assert.assertEquals(1,
metricsTestRegistrar.getCounterValue(SiembolMetrics.RESPONSE_RULES_ERROR_UPDATE.getMetricName()));
}
}

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>uk.co.gresearch.siembol</groupId>
<artifactId>siembol</artifactId>
<version>2.4.0-SNAPSHOT</version>
<version>2.4.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
@@ -184,6 +184,12 @@
<version>${slf4j_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.8.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
</build>

View File

@@ -0,0 +1,7 @@
package uk.co.gresearch.siembol.common.metrics;
public interface SiembolCounter {
void increment();
void increment(int value);
}

View File

@@ -0,0 +1,15 @@
package uk.co.gresearch.siembol.common.metrics;
import java.util.concurrent.atomic.AtomicInteger;
public class SiembolGauge {
private final AtomicInteger value = new AtomicInteger(0);
public void setValue(int value) {
this.value.set(value);
}
public int getValue() {
return value.intValue();
}
}

View File

@@ -0,0 +1,63 @@
package uk.co.gresearch.siembol.common.metrics;
public enum SiembolMetrics {
PARSING_CONFIGS_UPDATE("siembol_counter_parsing_configs_update"),
PARSING_CONFIGS_ERROR_UPDATE("siembol_counter_parsing_configs_error_update"),
PARSING_CONFIGS_UPDATE_VERSION("siembol_gauge_parsing_configs_update"),
PARSING_SOURCE_TYPE_PARSED_MESSAGES("siembol_counter_parsed_messages_%s"),
PARSING_SOURCE_TYPE_FILTERED_MESSAGES("siembol_counter_filtered_messages_%s"),
PARSING_APP_PARSED_MESSAGES("siembol_counter_app_parsed_messages"),
PARSING_APP_FILTERED_MESSAGES("siembol_counter_app_filtered_messages"),
PARSING_APP_ERROR_MESSAGES("siembol_counter_app_error_messages"),
ENRICHMENT_RULES_UPDATE("siembol_counter_enrichment_rules_update"),
ENRICHMENT_RULES_ERROR_UPDATE("siembol_counter_enrichment_rules_error_update"),
ENRICHMENT_RULES_UPDATE_VERSION("siembol_gauge_enrichment_rules_update"),
ENRICHMENT_RULE_APPLIED("siembol_counter_enrichment_rule_applied_%s"),
ENRICHMENT_TABLE_APPLIED("siembol_counter_enrichment_table_applied_%s"),
ENRICHMENT_TABLE_UPDATED("siembol_counter_enrichment_table_updated_%s"),
ENRICHMENT_TABLE_UPDATE_ERROR("siembol_counter_enrichment_table_error_update_%s"),
ALERTING_RULES_UPDATE("siembol_counter_alerting_rules_update"),
ALERTING_RULES_ERROR_UPDATE("siembol_counter_alerting_rules_error_update"),
ALERTING_RULES_UPDATE_VERSION("siembol_gauge_enrichment_rules_update"),
ALERTING_RULE_MATCHES("siembol_counter_alerting_rule_matches_%s"),
ALERTING_RULE_CORRELATION_MATCHES("siembol_counter_alerting_rule_for_correlation_matches_%s"),
ALERTING_RULE_ERROR_MATCHES("siembol_counter_alerting_rule_error_match_%s"),
ALERTING_RULE_PROTECTION("siembol_counter_alerting_rule_protection_%s"),
ALERTING_ENGINE_MATCHES("siembol_counter_alerting_engine_rules_matches"),
ALERTING_ENGINE_ERROR_MATCHES("siembol_counter_alerting_engine_error_matches"),
ALERTING_ENGINE_CORRELATION_MATCHES("siembol_counter_alerting_engine_rules_for_correlation_matches"),
ALERTING_ENGINE_RULE_PROTECTION("siembol_counter_alerting_engine_rules_protection_matches"),
RESPONSE_RULE_MATCHES("siembol_counter_response_rule_matches_%s"),
RESPONSE_RULE_ERROR_MATCHES("siembol_counter_response_rule_error_matches_%s"),
RESPONSE_RULE_FILTERED_ALERTS("siembol_counter_response_rule_filters_%s"),
RESPONSE_ENGINE_PROCESSED_ALERTS("siembol_counter_response_engine_processed_alerts"),
RESPONSE_ENGINE_FILTERED_ALERTS("siembol_counter_response_engine_filtered_alerts"),
RESPONSE_ENGINE_ERRORS("siembol_counter_response_engine_errors"),
RESPONSE_ENGINE_NO_MATCHES("siembol_counter_response_engine_no_matches"),
RESPONSE_RULES_UPDATE("siembol_counter_response_rules_update"),
RESPONSE_RULES_ERROR_UPDATE("siembol_counter_response_rules_error_update"),
TOPOLOGY_MANAGER_TOPOLOGY_KILLED("siembol_counter_topology_killed_%s_%s"),
TOPOLOGY_MANAGER_TOPOLOGY_RELEASED("siembol_counter_topology_released_%s_%s"),
SIEMBOL_SYNC_RELEASE("siembol_counter_sync_release_%s"),
SIEMBOL_SYNC_ADMIN_CONFIG("siembol_counter_sync_admin_config_%s"),
SIEMBOL_SYNC_RULES_VERSION("siembol_counter_sync_config_version_%s"),
CONFIG_EDITOR_REST_RELEASE_PR_SERVICE("siembol_counter_release_pr_%s"),
CONFIG_EDITOR_REST_ADMIN_CONFIG_PR_SERVICE("siembol_counter_admin_counfig_pr_%s");
private final String formatStringName;
SiembolMetrics(String formatStringName) {
this.formatStringName = formatStringName;
}
public String getMetricName(String... args) {
return String.format(formatStringName, args);
}
}

View File

@@ -0,0 +1,35 @@
package uk.co.gresearch.siembol.common.metrics;
import java.util.HashMap;
import java.util.Map;
public class SiembolMetricsCachedRegistrar implements SiembolMetricsRegistrar {
private final Map<String, SiembolCounter> countersCache = new HashMap<>();
private final Map<String, SiembolGauge> gaugeCache = new HashMap<>();
private final SiembolMetricsRegistrar factory;
public SiembolMetricsCachedRegistrar(SiembolMetricsRegistrar factory) {
this.factory = factory;
}
@Override
public SiembolCounter registerCounter(String name) {
if (countersCache.containsKey(name)) {
return countersCache.get(name);
}
var counter = factory.registerCounter(name);
countersCache.put(name, counter);
return counter;
}
@Override
public SiembolGauge registerGauge(String name) {
if (gaugeCache.containsKey(name)) {
return gaugeCache.get(name);
}
var gauge = factory.registerGauge(name);
gaugeCache.put(name, gauge);
return gauge;
}
}

View File

@@ -0,0 +1,11 @@
package uk.co.gresearch.siembol.common.metrics;
public interface SiembolMetricsRegistrar {
SiembolCounter registerCounter(String name);
SiembolGauge registerGauge(String name);
default SiembolMetricsRegistrar cachedRegistrar() {
return new SiembolMetricsCachedRegistrar(this);
}
}

View File

@@ -0,0 +1,22 @@
package uk.co.gresearch.siembol.common.metrics.spring;
import io.micrometer.core.instrument.Counter;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
public class SpringCounter implements SiembolCounter {
private final Counter counter;
public SpringCounter(Counter counter) {
this.counter = counter;
}
@Override
public void increment() {
counter.increment();
}
@Override
public void increment(int value) {
counter.increment(value);
}
}

View File

@@ -0,0 +1,31 @@
package uk.co.gresearch.siembol.common.metrics.spring;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolGauge;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
public class SpringMetricsRegistrar implements SiembolMetricsRegistrar {
private final MeterRegistry registry;
public SpringMetricsRegistrar(MeterRegistry registry) {
this.registry = registry;
}
@Override
public SiembolCounter registerCounter(String name) {
return new SpringCounter(Counter.builder(name).register(registry));
}
@Override
public SiembolGauge registerGauge(String name) {
var gauge = new SiembolGauge();
Gauge
.builder(name, () -> gauge.getValue())
.register(registry);
return gauge;
}
}

View File

@@ -0,0 +1,22 @@
package uk.co.gresearch.siembol.common.metrics.storm;
import com.codahale.metrics.Counter;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
public class StormCounter implements SiembolCounter {
private final Counter stormCounter;
public StormCounter(Counter stormCounter) {
this.stormCounter = stormCounter;
}
@Override
public void increment() {
stormCounter.inc();
}
@Override
public void increment(int value) {
stormCounter.inc(value);
}
}

View File

@@ -0,0 +1,24 @@
package uk.co.gresearch.siembol.common.metrics.storm;
import org.apache.storm.task.TopologyContext;
import uk.co.gresearch.siembol.common.metrics.*;
public class StormMetricsRegistrar implements SiembolMetricsRegistrar {
private final TopologyContext topologyContext;
public StormMetricsRegistrar(TopologyContext topologyContext) {
this.topologyContext = topologyContext;
}
@Override
public SiembolCounter registerCounter(String name) {
return new StormCounter(topologyContext.registerCounter(name));
}
@Override
public SiembolGauge registerGauge(String name) {
final var gauge = new SiembolGauge();
topologyContext.registerGauge(name, () -> gauge.getValue());
return gauge;
}
}

View File

@@ -0,0 +1,8 @@
package uk.co.gresearch.siembol.common.metrics.storm;
import org.apache.storm.task.TopologyContext;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
public interface StormMetricsRegistrarFactory {
SiembolMetricsRegistrar createSiembolMetricsRegistrar(TopologyContext topologyContext);
}

View File

@@ -0,0 +1,14 @@
package uk.co.gresearch.siembol.common.metrics.storm;
import org.apache.storm.task.TopologyContext;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import java.io.Serializable;
public class StormMetricsRegistrarFactoryImpl implements StormMetricsRegistrarFactory, Serializable {
private static final long serialVersionUID = 1L;
@Override
public SiembolMetricsRegistrar createSiembolMetricsRegistrar(TopologyContext topologyContext) {
return new StormMetricsRegistrar(topologyContext).cachedRegistrar();
}
}

View File

@@ -0,0 +1,42 @@
package uk.co.gresearch.siembol.common.metrics.test;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolGauge;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import java.util.HashMap;
import java.util.Map;
public class SiembolMetricsTestRegistrar implements SiembolMetricsRegistrar {
private final Map<String, SiembolTestCounter> countersMap = new HashMap<>();
private final Map<String, SiembolGauge> gaugesMap = new HashMap<>();
private static final String METRIC_ALREADY_EXISTS_MSG = "Metric %s already exists";
private static final String METRIC_DOES_NOT_EXIST_MSG = "Metric %s does not exist";
@Override
public SiembolCounter registerCounter(String name) {
if (countersMap.containsKey(name)) {
throw new IllegalArgumentException(String.format(METRIC_ALREADY_EXISTS_MSG, name));
}
var counter = new SiembolTestCounter();
countersMap.put(name, counter);
return counter;
}
@Override
public SiembolGauge registerGauge(String name) {
if (countersMap.containsKey(name)) {
throw new IllegalArgumentException(String.format(METRIC_ALREADY_EXISTS_MSG, name));
}
var gauge = new SiembolGauge();
gaugesMap.put(name, gauge);
return gauge;
}
public int getCounterValue(String name) {
if (!countersMap.containsKey(name)) {
throw new IllegalArgumentException(String.format(METRIC_DOES_NOT_EXIST_MSG, name));
}
return countersMap.get(name).getValue();
}
}

View File

@@ -0,0 +1,22 @@
package uk.co.gresearch.siembol.common.metrics.test;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import java.util.concurrent.atomic.AtomicInteger;
public class SiembolTestCounter implements SiembolCounter {
private final AtomicInteger counter = new AtomicInteger(0);
@Override
public void increment() {
counter.incrementAndGet();
}
@Override
public void increment(int value) {
counter.addAndGet(value);
}
public int getValue() {
return counter.get();
}
}

View File

@@ -0,0 +1,24 @@
package uk.co.gresearch.siembol.common.metrics.test;
import org.apache.storm.task.TopologyContext;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
public class StormMetricsTestRegistrarFactoryImpl implements StormMetricsRegistrarFactory {
private final SiembolMetricsTestRegistrar metricsRegistrar;
private final SiembolMetricsRegistrar cachedRegistrar;
public StormMetricsTestRegistrarFactoryImpl() {
metricsRegistrar = new SiembolMetricsTestRegistrar();
cachedRegistrar = metricsRegistrar.cachedRegistrar();
}
@Override
public SiembolMetricsRegistrar createSiembolMetricsRegistrar(TopologyContext topologyContext) {
return cachedRegistrar;
}
public int getCounterValue(String name) {
return metricsRegistrar.getCounterValue(name);
}
}

View File

@@ -16,4 +16,5 @@ public class AdminConfigDto {
public void setConfigVersion(Integer configVersion) {
this.configVersion = configVersion;
}
}

View File

@@ -1,30 +1,43 @@
package uk.co.gresearch.siembol.common.storm;
import org.apache.storm.tuple.Tuple;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class KafkaWriterAnchor {
private final Tuple tuple;
private final AtomicInteger counter = new AtomicInteger(0);
private final ArrayList<SiembolCounter> siembolCounters = new ArrayList<>();
private final AtomicInteger referenceCounter = new AtomicInteger(0);
public KafkaWriterAnchor(Tuple tuple) {
this.tuple = tuple;
}
public void acquire() {
counter.incrementAndGet();
referenceCounter.incrementAndGet();
}
public void acquire(int number) {
counter.addAndGet(number);
referenceCounter.addAndGet(number);
}
public boolean release() {
return counter.decrementAndGet() <= 0;
return referenceCounter.decrementAndGet() <= 0;
}
public Tuple getTuple() {
return tuple;
}
public void addSiembolCounters(List<SiembolCounter> counters) {
siembolCounters.addAll(counters);
}
public void incrementSiembolCounters() {
siembolCounters.forEach(SiembolCounter::increment);
}
}

View File

@@ -3,6 +3,7 @@ package uk.co.gresearch.siembol.common.storm;
import org.apache.storm.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import uk.co.gresearch.siembol.common.model.KafkaBatchWriterAttributesDto;
import java.lang.invoke.MethodHandles;
@@ -12,11 +13,17 @@ public class KafkaWriterBolt extends KafkaWriterBoltBase {
private static final Logger LOG =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String MISSING_MESSAGES_MSG = "Missing messages in tuple";
private static final String MISSING_COUNTERS_MSG = "Missing counters in tuple";
private final String fieldName;
private final String countersFieldName;
public KafkaWriterBolt(KafkaBatchWriterAttributesDto attributes, String fieldName) {
super(attributes.getProducerProperties().getProperties());
public KafkaWriterBolt(KafkaBatchWriterAttributesDto attributes,
String fieldName,
String countersFieldName,
StormMetricsRegistrarFactory metricsFactory) {
super(attributes.getProducerProperties().getProperties(), metricsFactory);
this.fieldName = fieldName;
this.countersFieldName = countersFieldName;
}
@Override
@@ -26,14 +33,20 @@ public class KafkaWriterBolt extends KafkaWriterBoltBase {
LOG.error(MISSING_MESSAGES_MSG);
throw new IllegalStateException(MISSING_MESSAGES_MSG);
}
KafkaWriterMessages currentMessages = (KafkaWriterMessages)messagesObject;
if (currentMessages.isEmpty()) {
LOG.error(MISSING_MESSAGES_MSG);
throw new IllegalStateException(MISSING_MESSAGES_MSG);
}
Object countersObject = tuple.getValueByField(countersFieldName);
if (!(countersObject instanceof SiembolMetricsCounters)) {
LOG.error(MISSING_COUNTERS_MSG);
throw new IllegalStateException(MISSING_COUNTERS_MSG);
}
var counters = (SiembolMetricsCounters)countersObject;
var anchor = new KafkaWriterAnchor(tuple);
writeMessages(currentMessages, anchor);
writeMessages(currentMessages, counters, anchor);
}
}

View File

@@ -12,11 +12,15 @@ import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gresearch.siembol.common.metrics.SiembolCounter;
import uk.co.gresearch.siembol.common.metrics.SiembolMetricsRegistrar;
import uk.co.gresearch.siembol.common.metrics.storm.StormMetricsRegistrarFactory;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
public abstract class KafkaWriterBoltBase extends BaseRichBolt {
private static final long serialVersionUID = 1L;
@@ -30,22 +34,26 @@ public abstract class KafkaWriterBoltBase extends BaseRichBolt {
"Sending message: {}, key :{} to the topic: {} ";
private final Properties props;
private final StormMetricsRegistrarFactory metricsFactory;
private OutputCollector collector;
private Producer<String, String> producer;
private SiembolMetricsRegistrar metricsRegistrar;
protected KafkaWriterBoltBase(Properties producerProperties) {
protected KafkaWriterBoltBase(Properties producerProperties, StormMetricsRegistrarFactory metricsFactory) {
this.props = producerProperties;
this.metricsFactory = metricsFactory;
}
@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
this.collector = outputCollector;
producer = new KafkaProducer<>(props, new StringSerializer(), new StringSerializer());
metricsRegistrar = metricsFactory.createSiembolMetricsRegistrar(topologyContext);
prepareInternally();
}
protected void prepareInternally() {
}
protected void prepareInternally() {
}
@Override
public void cleanup() {
@@ -56,8 +64,12 @@ public abstract class KafkaWriterBoltBase extends BaseRichBolt {
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
}
protected void writeMessages(List<KafkaWriterMessage> messages, KafkaWriterAnchor anchor) {
protected void writeMessages(List<KafkaWriterMessage> messages, List<String> countersNames, KafkaWriterAnchor anchor) {
anchor.acquire(messages.size());
List<SiembolCounter> siembolCounters = countersNames.stream()
.map(x -> metricsRegistrar.registerCounter(x))
.collect(Collectors.toList());
anchor.addSiembolCounters(siembolCounters);
messages.forEach(x -> writeMessage(x, anchor));
}
@@ -69,6 +81,7 @@ public abstract class KafkaWriterBoltBase extends BaseRichBolt {
collector.fail(anchor.getTuple());
} else {
if (anchor.release()) {
anchor.incrementSiembolCounters();
collector.ack(anchor.getTuple());
}
}

View File

@@ -35,4 +35,5 @@ public class KafkaWriterMessage implements Serializable {
public ProducerRecord<String, String> getProducerRecord() {
return key == null ? new ProducerRecord<>(topic, message) : new ProducerRecord<>(topic, key, message);
}
}

View File

@@ -0,0 +1,7 @@
package uk.co.gresearch.siembol.common.storm;
import java.util.ArrayList;
public class SiembolMetricsCounters extends ArrayList<String> {
private static final long serialVersionUID = 1L;
}