private void onQuery(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); String query = tuple.getString(TopologyConstants.QUERY_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.QUERY_METADATA_POSITION); // bufferedMetadata has an entry for each query that exists in the JoinBolt; therefore, we check bufferedMetadata // for existing queries (as opposed to individually checking the queries, preStartBuffer, and postFinishBuffer maps) if (bufferedMetadata.containsKey(id)) { updateCount(duplicatedQueriesCount, 1L); log.error("Duplicate for request {} with query {}", id, query); return; } Querier querier; try { querier = createQuerier(Querier.Mode.ALL, id, query, config); Optional<List<BulletError>> optionalErrors = querier.initialize(); if (!optionalErrors.isPresent()) { setupQuery(id, query, metadata, querier); return; } emitErrorsAsResult(id, metadata, optionalErrors.get()); } catch (RuntimeException re) { // Includes JSONParseException emitErrorsAsResult(id, metadata, ParsingError.makeError(re, query)); } log.error("Failed to initialize query for request {} with query {}", id, query); }
private void onQuery(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); String query = tuple.getString(TopologyConstants.QUERY_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.QUERY_METADATA_POSITION); // bufferedMetadata has an entry for each query that exists in the JoinBolt; therefore, we check bufferedMetadata // for existing queries (as opposed to individually checking the queries, preStartBuffer, and postFinishBuffer maps) if (bufferedMetadata.containsKey(id)) { updateCount(duplicatedQueriesCount, 1L); log.error("Duplicate for request {} with query {}", id, query); return; } Querier querier; try { querier = createQuerier(Querier.Mode.ALL, id, query, config); Optional<List<BulletError>> optionalErrors = querier.initialize(); if (!optionalErrors.isPresent()) { setupQuery(id, query, metadata, querier); return; } emitErrorsAsResult(id, metadata, optionalErrors.get()); } catch (RuntimeException re) { // Includes JSONParseException emitErrorsAsResult(id, metadata, ParsingError.makeError(re, query)); } log.error("Failed to initialize query for request {} with query {}", id, query); }
@Test public void testErrorEmittedProperly() { Tuple query = TupleUtils.makeIDTuple(TupleClassifier.Type.QUERY_TUPLE, "42", "garbage", EMPTY); bolt.execute(query); Assert.assertEquals(collector.getEmittedCount(), 1); String error = ParsingError.GENERIC_JSON_ERROR + ":\ngarbage\n" + "IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $"; BulletError expectedError = ParsingError.makeError(error, ParsingError.GENERIC_JSON_RESOLUTION); Meta expectedMetadata = Meta.of(expectedError); List<Object> expected = TupleUtils.makeTuple("42", Clip.of(expectedMetadata).asJSON(), FAILED).getValues(); List<Object> actual = collector.getNthTupleEmittedTo(TopologyConstants.RESULT_STREAM, 1).get(); Assert.assertTrue(isSameResult(actual, expected)); }
@Test public void testUnhandledExceptionErrorEmitted() { // An empty query should throw an null-pointer exception which should be caught in JoinBolt // and an error should be emitted Tuple query = TupleUtils.makeIDTuple(TupleClassifier.Type.QUERY_TUPLE, "42", "", EMPTY); bolt.execute(query); sendRawRecordTuplesTo(bolt, "42"); Assert.assertEquals(collector.getEmittedCount(), 1); String error = ParsingError.GENERIC_JSON_ERROR + ":\n\nNullPointerException: "; BulletError expectedError = ParsingError.makeError(error, ParsingError.GENERIC_JSON_RESOLUTION); Meta expectedMetadata = Meta.of(expectedError); List<Object> expected = TupleUtils.makeTuple("42", Clip.of(expectedMetadata).asJSON(), FAILED).getValues(); List<Object> actual = collector.getNthTupleEmittedTo(TopologyConstants.RESULT_STREAM, 1).get(); Assert.assertTrue(isSameResult(actual, expected)); }