From 889746e76819420ed45e5d01b44af52e37969635 Mon Sep 17 00:00:00 2001 From: Taylor Gray Date: Fri, 20 Oct 2023 15:50:17 -0500 Subject: [PATCH] Reorder formatString expression check for JacksonEvent (#3533) Reorder formatString expression check for JacksonEvent Signed-off-by: Taylor Gray (cherry picked from commit 53a06bd5825e38d1c2a3fdb91678f43cdb2d5000) --- .../dataprepper/model/event/JacksonEvent.java | 16 +++++--- .../model/event/JacksonEventTest.java | 40 ++++++++++++++++++- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/data-prepper-api/src/main/java/org/opensearch/dataprepper/model/event/JacksonEvent.java b/data-prepper-api/src/main/java/org/opensearch/dataprepper/model/event/JacksonEvent.java index f1c5357a11..686ee1d59f 100644 --- a/data-prepper-api/src/main/java/org/opensearch/dataprepper/model/event/JacksonEvent.java +++ b/data-prepper-api/src/main/java/org/opensearch/dataprepper/model/event/JacksonEvent.java @@ -354,12 +354,18 @@ private String formatStringInternal(final String format, final ExpressionEvaluat result += format.substring(fromIndex, position); String name = format.substring(position + 2, endPosition); - Object val; - if (Objects.nonNull(expressionEvaluator) && expressionEvaluator.isValidExpressionStatement(name)) { - val = expressionEvaluator.evaluate(name, this); - } else { + Object val = null; + + try { val = this.get(name, Object.class); - if (val == null) { + } catch (final Exception e) { + LOG.debug("Received exception using Event key for formatting, now checking for Data Prepper expression: {}", e.getMessage()); + } + + if (val == null) { + if (Objects.nonNull(expressionEvaluator) && expressionEvaluator.isValidExpressionStatement(name)) { + val = expressionEvaluator.evaluate(name, this); + } else { throw new EventKeyNotFoundException(String.format("The key %s could not be found in the Event when formatting", name)); } } diff --git a/data-prepper-api/src/test/java/org/opensearch/dataprepper/model/event/JacksonEventTest.java b/data-prepper-api/src/test/java/org/opensearch/dataprepper/model/event/JacksonEventTest.java index f407d7ad12..62ce3dc48d 100644 --- a/data-prepper-api/src/test/java/org/opensearch/dataprepper/model/event/JacksonEventTest.java +++ b/data-prepper-api/src/test/java/org/opensearch/dataprepper/model/event/JacksonEventTest.java @@ -31,7 +31,12 @@ import static org.hamcrest.CoreMatchers.sameInstance; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.opensearch.dataprepper.test.matcher.MapEquals.isEqualWithoutTimestamp; @@ -549,14 +554,44 @@ public void testBuild_withIsValidFormatExpressionsWithNullEvaluator() { assertThat(JacksonEvent.isValidFormatExpressions("${}", null), equalTo(false)); } + @Test + public void formatString_with_expression_evaluator_catches_exception_when_Event_get_throws_exception() { + + final String jsonString = "{\"foo\": \"bar\", \"info\": {\"ids\": {\"id\":\"idx\"}}}"; + final String expressionStatement = UUID.randomUUID().toString(); + final String invalidKeyExpression = "getMetadata(\"metadata-key\")"; + final String invalidKeyExpressionResult = UUID.randomUUID().toString(); + final String expressionEvaluationResult = UUID.randomUUID().toString(); + + final String formatString = "${" + invalidKeyExpression + "}-${" + expressionStatement + "}-test-string"; + final String finalString = invalidKeyExpressionResult + "-" + expressionEvaluationResult + "-test-string"; + + event = JacksonEvent.builder() + .withEventType(eventType) + .withData(jsonString) + .getThis() + .build(); + + final ExpressionEvaluator expressionEvaluator = mock(ExpressionEvaluator.class); + + when(expressionEvaluator.isValidExpressionStatement("foo")).thenReturn(false); + when(expressionEvaluator.isValidExpressionStatement(expressionStatement)).thenReturn(true); + when(expressionEvaluator.isValidExpressionStatement(invalidKeyExpression)).thenReturn(true); + when(expressionEvaluator.evaluate(invalidKeyExpression, event)).thenReturn(invalidKeyExpressionResult); + when(expressionEvaluator.evaluate(expressionStatement, event)).thenReturn(expressionEvaluationResult); + + assertThat(event.formatString(formatString, expressionEvaluator), is(equalTo(finalString))); + } + @Test public void testBuild_withFormatStringWithExpressionEvaluator() { final String jsonString = "{\"foo\": \"bar\", \"info\": {\"ids\": {\"id\":\"idx\"}}}"; final String expressionStatement = UUID.randomUUID().toString(); final String expressionEvaluationResult = UUID.randomUUID().toString(); + final String eventKey = "foo"; - final String formatString = "${foo}-${" + expressionStatement + "}-test-string"; + final String formatString = "${" + eventKey + "}-${" + expressionStatement + "}-test-string"; final String finalString = "bar-" + expressionEvaluationResult + "-test-string"; event = JacksonEvent.builder() @@ -567,8 +602,9 @@ public void testBuild_withFormatStringWithExpressionEvaluator() { final ExpressionEvaluator expressionEvaluator = mock(ExpressionEvaluator.class); - when(expressionEvaluator.isValidExpressionStatement("foo")).thenReturn(false); + verify(expressionEvaluator, times(0)).isValidExpressionStatement(eventKey); when(expressionEvaluator.isValidExpressionStatement(expressionStatement)).thenReturn(true); + verify(expressionEvaluator, never()).evaluate(eq("foo"), any(Event.class)); when(expressionEvaluator.evaluate(expressionStatement, event)).thenReturn(expressionEvaluationResult); assertThat(event.formatString(formatString, expressionEvaluator), is(equalTo(finalString)));