/** * Error a set of tuples that may not contain a valid message. * * <p>Without a valid message, the source type is unknown. * <p>Without a valid message, the JSON message cannot be added to the error. * * @param e The exception that occurred. * @param tuple The tuple to error that may not contain a valid message. */ public void error(Throwable e, Tuple tuple) { LOG.error("Failing tuple", e); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.INDEXING_ERROR) .withThrowable(e); handleError(tuple, error); }
protected void handleError(String sensorType, byte[] originalMessage, Tuple tuple, Throwable ex, OutputCollector collector) { MetronError error = new MetronError() .withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(ex) .withSensorType(Collections.singleton(sensorType)) .addRawMessage(originalMessage); ErrorUtils.handleError(collector, error); }
public void error(String sensorType, Throwable e, Iterable<Tuple> tuples, MessageGetStrategy messageGetStrategy) { LOG.error(format("Failing %d tuple(s); sensorType=%s", Iterables.size(tuples), sensorType), e); tuples.forEach(t -> { MetronError error = new MetronError() .withSensorType(Collections.singleton(sensorType)) .withErrorType(Constants.ErrorType.INDEXING_ERROR) .withThrowable(e) .addRawMessage(messageGetStrategy.get(t)); collector.emit(Constants.ERROR_STREAM, new Values(error.getJSONObject())); }); if (handleCommit) { commit(tuples); } // there is only one error to report for all of the failed tuples collector.reportError(e); }
protected void handleError(String key, JSONObject rawMessage, String subGroup, JSONObject enrichedMessage, Exception e) { LOG.error("[Metron] Unable to enrich message: {}", rawMessage, e); if (key != null) { collector.emit(enrichmentType, new Values(key, enrichedMessage, subGroup)); } MetronError error = new MetronError() .withErrorType(Constants.ErrorType.ENRICHMENT_ERROR) .withThrowable(e) .addRawMessage(rawMessage); ErrorUtils.handleError(collector, error); }
.withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(throwable) .withSensorType(Collections.singleton(sensorType)) .withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(entry.getValue()) .withSensorType(Collections.singleton(sensorType))
LOG.error("[Metron] Unable to join messages: {}", message, e); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.ENRICHMENT_ERROR) .withMessage("Joining problem: " + message) .withThrowable(e)
.withErrorType(Constants.ErrorType.PARSER_INVALID) .withSensorType(Collections.singleton(sensorType)) .addRawMessage(message);
@Test public void testNonBatchErrorPathErrorInWrite() throws Exception { ParserConfigurations configurations = getConfigurations(1); String sensorType = "test"; Tuple t = mock(Tuple.class); when(t.toString()).thenReturn("tuple"); when(t.getValueByField(eq("message"))).thenReturn(new JSONObject()); WriterBolt bolt = new WriterBolt(new WriterHandler(writer), configurations, sensorType); bolt.prepare(new HashMap(), topologyContext, outputCollector); doThrow(new Exception("write error")).when(writer).write(any(), any(), any(), any()); verify(writer, times(1)).init(); bolt.execute(t); verify(outputCollector, times(1)).ack(t); verify(writer, times(1)).write(eq(sensorType), any(), any(), any()); verify(outputCollector, times(1)).reportError(any()); verify(outputCollector, times(0)).fail(any()); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.DEFAULT_ERROR) .withThrowable(new IllegalStateException("Unhandled bulk errors in response: {java.lang.Exception: write error=[tuple]}")) .withSensorType(Collections.singleton(sensorType)) .addRawMessage(new JSONObject()); verify(outputCollector, times(1)).emit(eq(Constants.ERROR_STREAM), argThat(new MetronErrorJSONMatcher(error.getJSONObject()))); }
@SuppressWarnings("unchecked") @Test public void testExecuteShouldReportError() throws ExecutionException { joinBolt.withMaxCacheSize(100); joinBolt.withMaxTimeRetain(10000); joinBolt.prepare(new HashMap(), topologyContext, outputCollector); when(tuple.getValueByField("key")).thenReturn(key); when(tuple.getValueByField("message")).thenReturn(new JSONObject()); joinBolt.cache = mock(LoadingCache.class); when(joinBolt.cache.get(any())).thenThrow(new RuntimeException(new Exception("join exception"))); joinBolt.execute(tuple); RuntimeException expectedExecutionException = new RuntimeException(new Exception("join exception")); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.ENRICHMENT_ERROR) .withMessage("Joining problem: {}") .withThrowable(expectedExecutionException) .addRawMessage(new JSONObject()); verify(outputCollector, times(1)).emit(eq(Constants.ERROR_STREAM), argThat(new MetronErrorJSONMatcher(error.getJSONObject()))); verify(outputCollector, times(1)).reportError(any(ExecutionException.class)); verify(outputCollector, times(1)).ack(eq(tuple)); verifyNoMoreInteractions(outputCollector); } }
@Test public void shouldExecuteWithMasterThrowable() { parserRunner = spy(parserRunner); RawMessage rawMessage = new RawMessage("raw_message".getBytes(), new HashMap<>()); Throwable masterThrowable = mock(Throwable.class); MessageParserResult<JSONObject> messageParserResult = new DefaultMessageParserResult<>(masterThrowable); when(broParser.parseOptionalResult(rawMessage.getMessage())).thenReturn(Optional.of(messageParserResult)); parserRunner.setSensorToParserComponentMap(new HashMap<String, ParserComponent>() {{ put("bro", new ParserComponent(broParser, stellarFilter)); }}); ParserRunnerResults<JSONObject> parserRunnerResults = parserRunner.execute("bro", rawMessage, parserConfigurations); verify(parserRunner, times(0)) .processMessage(any(), any(), any(), any(), any()); MetronError expectedError = new MetronError() .withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(masterThrowable) .withSensorType(Collections.singleton("bro")) .addRawMessage(rawMessage.getMessage()); Assert.assertEquals(1, parserRunnerResults.getErrors().size()); Assert.assertTrue(parserRunnerResults.getErrors().contains(expectedError)); }
expectedOutput.put("source.type", "bro"); MetronError expectedMetronError = new MetronError() .withErrorType(Constants.ErrorType.PARSER_INVALID) .withSensorType(Collections.singleton("bro")) .addRawMessage(inputMessage)
@Override public void execute(Tuple tuple) { JSONObject message = null; try { message = (JSONObject) messageGetStrategy.get(tuple); handler.write(sensorType, tuple, message, configuration, messageGetStrategy); if(!handler.handleAck()) { collector.ack(tuple); } } catch (Throwable e) { MetronError error = new MetronError() .withErrorType(errorType) .withThrowable(e) .withSensorType(Collections.singleton(sensorType)) .addRawMessage(message); ErrorUtils.handleError(collector, error); collector.ack(tuple); } }
LOG.error("[Metron] Unable to enrich message: {}", message, t); MetronError error = new MetronError() .withErrorType(strategy.getErrorType()) .withMessage(t.getValue().getMessage()) .withThrowable(t.getValue()) .withErrorType(strategy.getErrorType()) .withMessage(e.getMessage()) .withThrowable(e)
@Test public void shouldReturnMetronErrorOnInvalidMessage() { JSONObject inputMessage = new JSONObject(); inputMessage.put("guid", "guid"); RawMessage rawMessage = new RawMessage("raw_message".getBytes(), new HashMap<>()); JSONObject expectedOutput = new JSONObject(); expectedOutput.put("guid", "guid"); expectedOutput.put("source.type", "bro"); MetronError expectedMetronError = new MetronError() .withErrorType(Constants.ErrorType.PARSER_INVALID) .withSensorType(Collections.singleton("bro")) .addRawMessage(inputMessage); when(stellarFilter.emit(expectedOutput, parserRunner.getStellarContext())).thenReturn(true); when(broParser.validate(expectedOutput)).thenReturn(false); parserRunner.setSensorToParserComponentMap(new HashMap<String, ParserComponent>() {{ put("bro", new ParserComponent(broParser, stellarFilter)); }}); Optional<ParserRunnerImpl.ProcessResult> processResult = parserRunner.processMessage("bro", inputMessage, rawMessage, broParser, parserConfigurations); Assert.assertTrue(processResult.isPresent()); Assert.assertTrue(processResult.get().isError()); Assert.assertEquals(expectedMetronError, processResult.get().getError()); }
@Test public void getJSONObjectShouldReturnBasicInformation() { MetronError error = new MetronError() .withMessage("test message") .withErrorType(Constants.ErrorType.PARSER_ERROR) .withSensorType(Collections.singleton("sensorType")); JSONObject errorJSON = error.getJSONObject(); assertEquals("test message", errorJSON.get(Constants.ErrorFields.MESSAGE.getName())); assertEquals(Constants.ErrorType.PARSER_ERROR.getType(), errorJSON.get(Constants.ErrorFields.ERROR_TYPE.getName())); assertEquals("error", errorJSON.get(Constants.SENSOR_TYPE)); assertEquals("sensorType", errorJSON.get(Constants.ErrorFields.FAILED_SENSOR_TYPE.getName())); String hostName = null; try { hostName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException uhe) { // unable to get the hostname on this machine, don't test it } if (!StringUtils.isEmpty(hostName)) { assertTrue(((String) errorJSON.get(Constants.ErrorFields.HOSTNAME.getName())).length() > 0); assertEquals(hostName, (String) errorJSON.get(Constants.ErrorFields.HOSTNAME.getName())); } assertTrue(((long) errorJSON.get(Constants.ErrorFields.TIMESTAMP.getName())) > 0); }
@Override public ParserRunnerResults<JSONObject> execute(String sensorType, RawMessage rawMessage, ParserConfigurations parserConfigurations) { DefaultParserRunnerResults parserRunnerResults = new DefaultParserRunnerResults(); this.rawMessage = rawMessage; if (!isInvalid) { parserRunnerResults.addMessage(message); } else { MetronError error = new MetronError() .withErrorType(Constants.ErrorType.PARSER_INVALID) .withSensorType(Collections.singleton(sensorType)) .addRawMessage(message); parserRunnerResults.addError(error); } return parserRunnerResults; }
}}); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(new IllegalStateException("parserRunner.execute failed")) .withSensorType(Collections.singleton("yaf"))
.withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(new IllegalStateException("write failed")) .withSensorType(Collections.singleton("yaf"))
.withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(throwable1) .withSensorType(Collections.singleton("bro")) .addRawMessage(rawMessage1); MetronError expectedParseError2 = new MetronError() .withErrorType(Constants.ErrorType.PARSER_ERROR) .withThrowable(throwable2) .withSensorType(Collections.singleton("bro"))
RawMessage expectedRawMessage = new RawMessage("originalMessage".getBytes(StandardCharsets.UTF_8), new HashMap<>()); MetronError error = new MetronError() .withErrorType(Constants.ErrorType.PARSER_INVALID) .withSensorType(Collections.singleton("yaf")) .addRawMessage(message);