From e9a0de788824cd58e5161bcdc19e135d0943c517 Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Mon, 1 Nov 2021 00:23:45 -0400 Subject: [PATCH 1/6] added logstash visitor to populate logstash model POJO's Signed-off-by: Asif Sohail Mohammed --- build.gradle | 1 + config/checkstyle/checkstyle-suppressions.xml | 9 + config/checkstyle/checkstyle.xml | 4 + .../build.gradle | 23 + .../src/main/antlr/Logstash.g4 | 138 +++++ .../LogstashConfigurationException.java | 8 + .../exception/LogstashGrammarException.java | 8 + .../exception/LogstashParsingException.java | 8 + .../logstash/parser/LogstashVisitor.java | 171 ++++++ .../logstash/parser/LogstashVisitorTest.java | 559 ++++++++++++++++++ .../logstash/parser/TestDataProvider.java | 123 ++++ 11 files changed, 1052 insertions(+) create mode 100644 config/checkstyle/checkstyle-suppressions.xml create mode 100644 data-prepper-logstash-configuration/build.gradle create mode 100644 data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 create mode 100644 data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java create mode 100644 data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java create mode 100644 data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java create mode 100644 data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java create mode 100644 data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java create mode 100644 data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java diff --git a/build.gradle b/build.gradle index ab34ff88d3..1ce0378408 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,7 @@ subprojects { sourceCompatibility = '1.8' spotless { java { + targetExclude 'build/generated-src/antlr/**' // TODO: enrich format rules removeUnusedImports() } diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml new file mode 100644 index 0000000000..28bea50b3e --- /dev/null +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index aa0ad55f3f..dda71724f4 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -6,6 +6,10 @@ + + + + diff --git a/data-prepper-logstash-configuration/build.gradle b/data-prepper-logstash-configuration/build.gradle new file mode 100644 index 0000000000..4189d3ffba --- /dev/null +++ b/data-prepper-logstash-configuration/build.gradle @@ -0,0 +1,23 @@ +plugins { + id 'java' + id 'antlr' + id 'idea' +} + +repositories { + mavenCentral() +} + +dependencies { + antlr "org.antlr:antlr4:4.9.2" + testImplementation "org.hamcrest:hamcrest:2.2" + testImplementation "org.mockito:mockito-inline:${versionMap.mockito}" + testImplementation platform("org.junit:junit-bom:${versionMap.junitJupiter}") +} + +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-listener', '-visitor'] + outputDirectory = new File("build/generated-src/antlr/main/org/opensearch/dataprepper/logstash/".toString()) +} +compileJava.dependsOn generateGrammarSource diff --git a/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 new file mode 100644 index 0000000000..a3d169ac6d --- /dev/null +++ b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 @@ -0,0 +1,138 @@ +grammar Logstash; + +@header { + package org.opensearch.dataprepper.logstash; +} +/* +* Parser Rules +*/ +config: filler plugin_section filler (filler plugin_section)* filler; + +filler: (COMMENT | WS | NEWLINE)*; + +plugin_section: plugin_type filler '{' + filler (branch_or_plugin filler)* + '}'; + +plugin_type: ('input' | 'filter' | 'output'); + +branch_or_plugin: branch | plugin; + +plugin: + name filler '{' + filler + attributes + filler + '}'; + +attributes:( attribute (filler attribute)*)?; + +attribute: name filler '=>' filler value; + +name: BAREWORD | STRING; + +value: plugin | BAREWORD | STRING | NUMBER | array | hash; + +branch: r_if (filler else_if)* (filler r_else)?; + +r_if: 'if' filler condition filler '{' filler (branch_or_plugin filler)* '}'; + +else_if: 'else' filler 'if' filler condition filler '{' filler ( branch_or_plugin filler)* '}'; + +r_else: 'else' filler '{' filler (branch_or_plugin filler)* '}'; + +condition: expression (filler boolean_operator filler expression)*; + +expression: + ( + ('(' filler condition filler ')') + | negative_expression + | in_expression + | not_in_expression + | compare_expression + | regexp_expression + | rvalue + ); + +array: + '[' + filler + ( + value (filler ',' filler value)* + )? + filler + ']'; + +hash: + '{' + filler + hashentries? + filler + '}'; + +hashentries: hashentry (WS hashentry)*; + +hashentry: hashname filler '=>' filler value; + +hashname: BAREWORD | STRING | NUMBER; + +boolean_operator: ('and' | 'or' | 'xor' | 'nand'); + +negative_expression: + ( + ('!' filler '(' filler condition filler ')') + | ('!' filler selector) + ); + +in_expression: rvalue filler in_operator filler rvalue; + +not_in_expression: rvalue filler not_in_operator filler rvalue; + +rvalue: STRING | NUMBER | selector | array | method_call | regexp; + +regexp: '/' ('^' | '\\' | '.' | '+' |.)*? '/'; + +selector: selector_element+; + +compare_expression: rvalue filler compare_operator filler rvalue; + +regexp_expression: rvalue filler regexp_operator filler (STRING | regexp); + +selector_element: '[' ~( '[' | ']' | ',' )+ ']'; + +in_operator: 'in'; + +not_in_operator: 'not' filler 'in'; + +method_call: + BAREWORD filler '(' filler + ( + rvalue ( filler ',' filler rvalue )* + )? + filler ')'; + +compare_operator: ('==' | '!=' | '<=' | '>=' | '<' | '>') ; + +regexp_operator: ('=~' | '!~'); + +/* +* Lexer Rules +*/ + +COMMENT: (WS? '#' ~('\r'|'\n')*)+; + +NEWLINE: ('\r'? '\n' | '\r')+ -> skip; + +WS: ( NEWLINE | ' ' | '\t' | '\r')+; + +fragment DIGIT: [0-9]; + +NUMBER: '-'? DIGIT+ ('.' DIGIT*)?; + +BAREWORD: [a-zA-Z0-9_]+; + +STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING; + +fragment DOUBLE_QUOTED_STRING : ('"' ( '\\"' | . )*? '"'); + +fragment SINGLE_QUOTED_STRING : ('\'' ( . )*? '\''); \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java new file mode 100644 index 0000000000..bc6b2d3977 --- /dev/null +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java @@ -0,0 +1,8 @@ +package org.opensearch.dataprepper.logstash.exception; + +public class LogstashConfigurationException extends RuntimeException { + + public LogstashConfigurationException(String errorMessage) { + super(errorMessage); + } +} diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java new file mode 100644 index 0000000000..5c55d726ff --- /dev/null +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java @@ -0,0 +1,8 @@ +package org.opensearch.dataprepper.logstash.exception; + +public class LogstashGrammarException extends LogstashParsingException { + + public LogstashGrammarException(String errorMessage) { + super(errorMessage); + } +} \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java new file mode 100644 index 0000000000..b406732fd8 --- /dev/null +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java @@ -0,0 +1,8 @@ +package org.opensearch.dataprepper.logstash.exception; + +public class LogstashParsingException extends LogstashConfigurationException { + + public LogstashParsingException(String errorMessage) { + super(errorMessage); + } +} \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java new file mode 100644 index 0000000000..b75f0c397e --- /dev/null +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java @@ -0,0 +1,171 @@ +package org.opensearch.dataprepper.logstash.parser; + +import org.opensearch.dataprepper.logstash.exception.LogstashParsingException; +import org.opensearch.dataprepper.logstash.LogstashBaseVisitor; +import org.opensearch.dataprepper.logstash.LogstashParser; +import org.opensearch.dataprepper.logstash.model.LogstashConfiguration; +import org.opensearch.dataprepper.logstash.model.LogstashPlugin; +import org.opensearch.dataprepper.logstash.model.LogstashAttribute; +import org.opensearch.dataprepper.logstash.model.LogstashAttributeValue; +import org.opensearch.dataprepper.logstash.model.LogstashPluginType; +import org.opensearch.dataprepper.logstash.model.LogstashValueType; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.LinkedList; +import java.util.ArrayList; + +/** + * Class to populate Logstash configuration model POJO's using ANTLR + * + * @since 1.2 + */ + +@SuppressWarnings("rawtypes") +public class LogstashVisitor extends LogstashBaseVisitor { + + private List logstashPluginList; + private final Map> pluginSections = new LinkedHashMap<>(); + private final Map hashEntries = new LinkedHashMap<>(); + + @Override + public Object visitConfig(LogstashParser.ConfigContext ctx) { + for(int i = 0; i < ctx.plugin_section().size(); i++) { + visitPlugin_section(ctx.plugin_section().get(i)); + } + return LogstashConfiguration.builder() + .pluginSections(pluginSections) + .build(); + } + + @Override + public Object visitPlugin_section(LogstashParser.Plugin_sectionContext ctx) { + + LogstashPluginType logstashPluginType; + logstashPluginList = new LinkedList<>(); + + switch (ctx.plugin_type().getText()) { + case "input": + logstashPluginType = LogstashPluginType.INPUT; + break; + case "filter": + logstashPluginType = LogstashPluginType.FILTER; + break; + case "output": + logstashPluginType = LogstashPluginType.OUTPUT; + break; + default: + throw new LogstashParsingException("only input, filter and output plugin sections are supported."); + } + + for (int i = 0; i < ctx.branch_or_plugin().size(); i++) { + logstashPluginList.add((LogstashPlugin) visitBranch_or_plugin(ctx.branch_or_plugin().get(i))); + } + + pluginSections.put(logstashPluginType, logstashPluginList); + + return pluginSections; + } + + @Override + public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext ctx) { + + if (ctx.getChild(0) instanceof LogstashParser.PluginContext) { + return visitPlugin(ctx.plugin()); + } + else { + throw new LogstashParsingException("conditionals are not supported"); + } + } + + @Override + public Object visitPlugin(LogstashParser.PluginContext ctx) { + String pluginName = ctx.name().getText(); + List logstashAttributeList = new ArrayList<>(); + + for (int i = 0; i < ctx.attributes().attribute().size(); i++) { + logstashAttributeList.add((LogstashAttribute) visitAttribute(ctx.attributes().attribute().get(i))); + } + + return LogstashPlugin.builder() + .pluginName(pluginName) + .attributes(logstashAttributeList) + .build(); + } + + @Override + public Object visitAttribute(LogstashParser.AttributeContext ctx) { + LogstashValueType logstashValueType = null; + Object value = null; + + if (ctx.value().getChild(0) instanceof LogstashParser.ArrayContext) { + logstashValueType = LogstashValueType.ARRAY; + value = visitArray(ctx.value().array()); + } + else if (ctx.value().getChild(0) instanceof LogstashParser.HashContext) { + logstashValueType = LogstashValueType.HASH; + value = visitHash(ctx.value().hash()); + } + else if (ctx.value().getChild(0) instanceof LogstashParser.PluginContext) { + throw new LogstashParsingException("plugins are not supported in attribute"); + } + + else if (ctx.value().NUMBER() != null && ctx.value().getText().equals(ctx.value().NUMBER().toString())) { + logstashValueType = LogstashValueType.NUMBER; + value = Double.valueOf(ctx.value().getText()); + } + else if (ctx.value().BAREWORD() != null && ctx.value().getText().equals(ctx.value().BAREWORD().toString())) { + logstashValueType = LogstashValueType.BAREWORD; + value = ctx.value().getText(); + } + else if (ctx.value().STRING() != null && ctx.value().getText().equals(ctx.value().STRING().toString())) { + logstashValueType = LogstashValueType.STRING; + value = ctx.value().getText().replaceAll("^\"|\"$|^'|'$", ""); + } + + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder() + .attributeValueType(logstashValueType) + .value(value) + .build(); + + return LogstashAttribute.builder() + .attributeName(ctx.name().getText()) + .attributeValue(logstashAttributeValue) + .build(); + } + + @Override + public Object visitArray(LogstashParser.ArrayContext ctx) { + List values = new LinkedList<>(); + + for(int i = 0; i < ctx.value().size(); i++) + values.add(ctx.value().get(i).getText() ); + return values; + } + + @Override + public Object visitHash(LogstashParser.HashContext ctx) { + return visitHashentries(ctx.hashentries()); + } + + @Override + public Object visitHashentries(LogstashParser.HashentriesContext ctx) { + for (int i = 0; i < ctx.hashentry().size(); i++) { + visitHashentry((ctx.hashentry().get(i))); + } + return hashEntries; + } + + @Override + public Object visitHashentry(LogstashParser.HashentryContext ctx) { + + if (ctx.value().getChild(0) instanceof LogstashParser.ArrayContext) + hashEntries.put(ctx.hashname().getText(), visitArray(ctx.value().array())); + + else + hashEntries.put(ctx.hashname().getText(), ctx.value().getText()); + + return hashEntries; + } +} \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java new file mode 100644 index 0000000000..5446a2b6da --- /dev/null +++ b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java @@ -0,0 +1,559 @@ +package org.opensearch.dataprepper.logstash.parser; + +import org.antlr.v4.runtime.tree.TerminalNodeImpl; +import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertThrows; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.mock; + +import org.mockito.Mockito; +import org.opensearch.dataprepper.logstash.LogstashParser; +import org.opensearch.dataprepper.logstash.exception.LogstashParsingException; +import org.opensearch.dataprepper.logstash.model.LogstashConfiguration; +import org.opensearch.dataprepper.logstash.model.LogstashPlugin; +import org.opensearch.dataprepper.logstash.model.LogstashPluginType; +import org.opensearch.dataprepper.logstash.model.LogstashAttribute; + +import java.util.Collections; +import java.util.Arrays; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; + +class LogstashVisitorTest { + + private LogstashVisitor createObjectUnderTest() { + return spy(new LogstashVisitor()); + } + + @Test + void visit_config_test() { + final LogstashParser.ConfigContext configContextMock = mock(LogstashParser.ConfigContext.class); + final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); + final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); + final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + + given(configContextMock.plugin_section()).willReturn(Collections.singletonList(pluginSectionMock)); + given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); + given(pluginTypeContextMock.getText()).willReturn("input"); + given(pluginSectionMock.branch_or_plugin()).willReturn(Collections.singletonList(branchOrPluginContextMock)); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.pluginWithOneArrayContextAttributeData()).when(logstashVisitor).visitBranch_or_plugin(branchOrPluginContextMock); + + LogstashConfiguration actualLogstashConfiguration = (LogstashConfiguration) logstashVisitor.visitConfig(configContextMock); + LogstashConfiguration expectedLogstashConfiguration = TestDataProvider.configData(); + + assertThat(actualLogstashConfiguration.getPluginSection(LogstashPluginType.INPUT).size(), + equalTo(expectedLogstashConfiguration.getPluginSection(LogstashPluginType.INPUT).size())); + Mockito.verify(logstashVisitor, Mockito.times(1)).visitPlugin_section(pluginSectionMock); + } + + @SuppressWarnings("unchecked") + @Test + void visit_plugin_section_test() { + final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); + final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); + final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + + given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); + given(pluginTypeContextMock.getText()).willReturn("input"); + + List branch_or_pluginContextList = new LinkedList<>( + Collections.singletonList(branchOrPluginContextMock) + ); + given(pluginSectionMock.branch_or_plugin()).willReturn(branch_or_pluginContextList); + given(branchOrPluginContextMock.getChild(0)).willReturn(pluginContextMock); + given(branchOrPluginContextMock.plugin()).willReturn(pluginContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.pluginWithOneArrayContextAttributeData()).when(logstashVisitor).visitPlugin(pluginContextMock); + + Map> actualPluginSections = (Map>) + logstashVisitor.visitPlugin_section(pluginSectionMock); + Map> expectedPluginSections = TestDataProvider.pluginSectionData(); + + assertThat(actualPluginSections.keySet(), equalTo(expectedPluginSections.keySet())); + assertThat(actualPluginSections.get(LogstashPluginType.INPUT).size(), + equalTo(expectedPluginSections.get(LogstashPluginType.INPUT).size())); + } + + @Test + void visit_plugin_section_with_unsupported_section_name_throws_logstash_parsing_exception_test() { + final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); + final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); + + given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); + given(pluginTypeContextMock.getText()).willReturn("inputt"); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + + Exception exception = assertThrows(LogstashParsingException.class, () -> + logstashVisitor.visitPlugin_section(pluginSectionMock)); + + String expectedMessage = "only input, filter and output plugin sections are supported."; + String actualMessage = exception.getMessage(); + + assertThat(expectedMessage, equalTo(actualMessage)); + } + + @Test + void visit_branch_or_plugin_with_branch_throws_logstash_parsing_exception_test() { + final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + final LogstashParser.BranchContext branchContextMock = mock(LogstashParser.BranchContext.class); + + given(branchOrPluginContextMock.getChild(0)).willReturn(branchContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + + Exception exception = assertThrows(LogstashParsingException.class, () -> + logstashVisitor.visitBranch_or_plugin(branchOrPluginContextMock)); + + String expectedMessage = "conditionals are not supported"; + String actualMessage = exception.getMessage(); + + assertThat(expectedMessage, equalTo(actualMessage)); + } + + @Test + void visit_branch_or_plugin_returns_logstash_plugin_test() { + final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + + given(branchOrPluginContextMock.getChild(0)).willReturn(pluginContextMock); + given(branchOrPluginContextMock.plugin()).willReturn(pluginContextMock); + given(pluginContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(pluginContextMock.attributes()).willReturn(attributesContextMock); + + List attributeContexts = new LinkedList<>(Collections.singletonList(attributeContextMock)); + given(pluginContextMock.attributes()).willReturn(attributesContextMock); + given(attributesContextMock.attribute()).willReturn(attributeContexts); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.attributeWithArrayTypeValueData()).when(logstashVisitor).visitAttribute(attributeContextMock); + + LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitBranch_or_plugin(branchOrPluginContextMock); + LogstashPlugin expectedLogstashPlugin = TestDataProvider.pluginWithOneArrayContextAttributeData(); + + assertThat(actualLogstashPlugin.getPluginName(), equalTo(expectedLogstashPlugin.getPluginName())); + for (int i = 0; i < actualLogstashPlugin.getAttributes().size(); i++) { + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeName(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeName())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType())); + } + + } + + @Test + void visit_plugin_with_no_attribute_test() { + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + + given(pluginContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(pluginContextMock.attributes()).willReturn(attributesContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); + + LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); + LogstashPlugin expectedLogstashPlugin = TestDataProvider.pluginWithNoAttributeData(); + + assertThat(actualLogstashPlugin.getPluginName(), equalTo(expectedLogstashPlugin.getPluginName())); + assertThat(actualLogstashPlugin.getAttributes().size(), equalTo(expectedLogstashPlugin.getAttributes().size())); + } + + @Test + void visit_plugin_with_one_array_context_attribute_test() { + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + + given(pluginContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(pluginContextMock.attributes()).willReturn(attributesContextMock); + + List attributeContexts = new LinkedList<>(Collections.singletonList(attributeContextMock)); + + given(attributesContextMock.attribute()).willReturn(attributeContexts); + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getChild(0)).willReturn(arrayContextMock); + given(valueContextMock.array()).willReturn(arrayContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); + + LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); + LogstashPlugin expectedLogstashPlugin = TestDataProvider.pluginWithOneArrayContextAttributeData(); + + assertThat(actualLogstashPlugin.getPluginName(), equalTo(expectedLogstashPlugin.getPluginName())); + assertThat(actualLogstashPlugin.getAttributes().size(), equalTo(expectedLogstashPlugin.getAttributes().size())); + + for (int i = 0; i < actualLogstashPlugin.getAttributes().size(); i++) { + + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeName(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeName())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType())); + } + } + + @Test + void visit_plugin_with_more_than_one_array_context_attribute_test() { + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + + given(pluginContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(pluginContextMock.attributes()).willReturn(attributesContextMock); + + List attributeContexts = new LinkedList<>(); + attributeContexts.add(attributeContextMock); + attributeContexts.add(attributeContextMock); + given(attributesContextMock.attribute()).willReturn(attributeContexts); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getChild(0)).willReturn(arrayContextMock); + given(valueContextMock.array()).willReturn(arrayContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); + + LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); + LogstashPlugin expectedLogstashPlugin = TestDataProvider.pluginWithMorThanOneArrayContextAttributeData(); + + assertThat(actualLogstashPlugin.getPluginName(), equalTo(expectedLogstashPlugin.getPluginName())); + assertThat(actualLogstashPlugin.getAttributes().size(), equalTo(expectedLogstashPlugin.getAttributes().size())); + + for (int i = 0; i < actualLogstashPlugin.getAttributes().size(); i++) { + + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeName(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeName())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getValue())); + assertThat(actualLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashPlugin.getAttributes().get(i).getAttributeValue().getAttributeValueType())); + } + } + + @Test + void visit_attribute_with_value_type_array_returns_correct_logstash_attribute_test() { + + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); + final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getChild(0)).willReturn(arrayContextMock); + given(valueContextMock.array()).willReturn(arrayContextMock); + + List valueContextList = new LinkedList<>(Arrays.asList(valueContextMock1, valueContextMock2)); + given(arrayContextMock.value()).willReturn(valueContextList); + given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithArrayTypeValueData(); + + assertThat(actualLogstashAttribute.getAttributeName(), + equalTo(expectedLogstashAttribute.getAttributeName())); + assertThat(actualLogstashAttribute.getAttributeValue().getValue(), + equalTo(expectedLogstashAttribute.getAttributeValue().getValue())); + assertThat(actualLogstashAttribute.getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashAttribute.getAttributeValue().getAttributeValueType())); + } + + @Test + void visit_attribute_with_value_type_hash_returns_correct_logstash_attribute_test() { + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); + final LogstashParser.HashContext hashContextMock = mock(LogstashParser.HashContext.class); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getChild(0)).willReturn(hashContextMock); + given(valueContextMock.hash()).willReturn(hashContextMock); + given(hashContextMock.hashentries()).willReturn(hashentriesContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.hashEntryStringData()).when(logstashVisitor).visitHashentries(hashentriesContextMock); + + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); + LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithHashTypeValueData(); + + assertThat(actualLogstashAttribute.getAttributeName(), + equalTo(expectedLogstashAttribute.getAttributeName())); + assertThat(actualLogstashAttribute.getAttributeValue().getValue(), + equalTo(expectedLogstashAttribute.getAttributeValue().getValue())); + assertThat(actualLogstashAttribute.getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashAttribute.getAttributeValue().getAttributeValueType())); + } + + @Test + void visit_attribute_with_value_type_plugin_throws_logstash_parsing_exception_test() { + + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getChild(0)).willReturn(pluginContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + + Exception exception = assertThrows(LogstashParsingException.class, () -> logstashVisitor.visitAttribute(attributeContextMock)); + + String expectedMessage = "plugins are not supported in attribute"; + String actualMessage = exception.getMessage(); + + assertThat(expectedMessage, equalTo(actualMessage)); + } + + @Test + void visit_attribute_with_value_type_number_returns_correct_logstash_attribute_test() { + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.NUMBER()).willReturn(terminalNodeMock); + given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_VALUE); + given(valueContextMock.NUMBER().toString()).willReturn(TestDataProvider.RANDOM_VALUE); + + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithNumberTypeValueData(); + + assertThat(actualLogstashAttribute.getAttributeName(), + equalTo(expectedLogstashAttribute.getAttributeName())); + assertThat(actualLogstashAttribute.getAttributeValue().getValue(), + equalTo(expectedLogstashAttribute.getAttributeValue().getValue())); + assertThat(actualLogstashAttribute.getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashAttribute.getAttributeValue().getAttributeValueType())); + } + + @Test + void visit_attribute_with_value_type_bare_word_returns_correct_logstash_attribute_test() { + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.BAREWORD()).willReturn(terminalNodeMock); + given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + given(valueContextMock.BAREWORD().toString()).willReturn(TestDataProvider.RANDOM_STRING_2); + + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithBareWordTypeValueData(); + + + assertThat(actualLogstashAttribute.getAttributeName(), + equalTo(expectedLogstashAttribute.getAttributeName())); + assertThat(actualLogstashAttribute.getAttributeValue().getValue(), + equalTo(expectedLogstashAttribute.getAttributeValue().getValue())); + assertThat(actualLogstashAttribute.getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashAttribute.getAttributeValue().getAttributeValueType())); + + } + + @Test + void visit_attribute_with_value_type_string_returns_correct_logstash_attribute_test() { + final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); + + given(attributeContextMock.name()).willReturn(nameContextMock); + given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(attributeContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.STRING()).willReturn(terminalNodeMock); + given(valueContextMock.getText()).willReturn("\"" + TestDataProvider.RANDOM_STRING_2 + "\""); + given(valueContextMock.STRING().toString()).willReturn("\"" + TestDataProvider.RANDOM_STRING_2 + "\""); + + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithStringTypeValueData(); + + assertThat(actualLogstashAttribute.getAttributeName(), + equalTo(expectedLogstashAttribute.getAttributeName())); + assertThat(actualLogstashAttribute.getAttributeValue().getValue(), + equalTo(expectedLogstashAttribute.getAttributeValue().getValue())); + assertThat(actualLogstashAttribute.getAttributeValue().getAttributeValueType(), + equalTo(expectedLogstashAttribute.getAttributeValue().getAttributeValueType())); + + } + + @Test + void visit_array_with_empty_array_returns_empty_list_test() { + + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + + given(arrayContextMock.value()).willReturn(Collections.emptyList()); + + Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + + assertThat(actualList, equalTo(Collections.emptyList())); + } + + @Test + void visit_array_with_singleton_array_returns_list_df_size_one_test() { + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + + given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(arrayContextMock.value()).willReturn(Collections.singletonList(valueContextMock)); + + Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + + assertThat(actualList, equalTo(Collections.singletonList(TestDataProvider.RANDOM_STRING_1))); + } + + @Test + void visit_array_with_array_of_size_more_than_one_returns_list_of_size_more_than_one_test() { + LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); + final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); + + List valueContextList = new LinkedList<>(Arrays.asList(valueContextMock1, valueContextMock2)); + + given(arrayContextMock.value()).willReturn(valueContextList); + given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + + Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + + assertThat(actualList, equalTo(TestDataProvider.arrayData())); + } + + @Test + void visit_hash_entries_with_string_value_returns_map_of_hash_entries_test() { + + final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); + final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); + + List hashentryContextList = new LinkedList<>( + Collections.singletonList(hashentryContextMock)); + + given(hashentriesContextMock.hashentry()).willReturn(hashentryContextList); + given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); + given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(hashentryContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + + Object actualMap = createObjectUnderTest().visitHashentries(hashentriesContextMock); + + assertThat(actualMap, equalTo(TestDataProvider.hashEntryStringData())); + } + + @Test + void visit_hash_entries_with_array_value_returns_map_of_hash_entries_test() { + + final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); + final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + + List hashentryContextList = new LinkedList<>( + Collections.singletonList(hashentryContextMock)); + + given(hashentriesContextMock.hashentry()).willReturn(hashentryContextList); + given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); + given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(hashentryContextMock.value()).willReturn(valueContextMock); + given(hashentryContextMock.value().getChild(0)).willReturn(arrayContextMock); + given(valueContextMock.array()).willReturn(arrayContextMock); + + LogstashVisitor logstashVisitor = createObjectUnderTest(); + Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); + + Object actualMap = logstashVisitor.visitHashentries(hashentriesContextMock); + + assertThat(actualMap, equalTo(TestDataProvider.hashEntryArrayData())); + } + + @Test + void visit_hash_entry_with_value_type_string_returns_string_object_test() { + final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); + final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + + given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); + given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(hashentryContextMock.value()).willReturn(valueContextMock); + given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + + Object actualValue = createObjectUnderTest().visitHashentry(hashentryContextMock); + + assertThat(actualValue, equalTo(TestDataProvider.hashEntryStringData())); + } + + @Test + void visit_hash_entry_with_array_value_type_returns_list_test() { + + final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); + final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); + final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); + final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); + + final List linkedListValuesMock = new LinkedList<>( + Arrays.asList(valueContextMock1, valueContextMock2) + ); + + given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); + given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(hashentryContextMock.value()).willReturn(valueContextMock); + given(hashentryContextMock.value().getChild(0)).willReturn(arrayContextMock); + given(valueContextMock.array()).willReturn(arrayContextMock); + given(arrayContextMock.value()).willReturn(linkedListValuesMock); + given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + + Object actualList = createObjectUnderTest().visitHashentry(hashentryContextMock); + + assertThat(actualList, equalTo(TestDataProvider.hashEntryArrayData())); + } + +} \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java new file mode 100644 index 0000000000..35fe0c40e0 --- /dev/null +++ b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java @@ -0,0 +1,123 @@ +package org.opensearch.dataprepper.logstash.parser; + +import org.opensearch.dataprepper.logstash.model.LogstashConfiguration; +import org.opensearch.dataprepper.logstash.model.LogstashPluginType; +import org.opensearch.dataprepper.logstash.model.LogstashPlugin; +import org.opensearch.dataprepper.logstash.model.LogstashAttribute; +import org.opensearch.dataprepper.logstash.model.LogstashAttributeValue; +import org.opensearch.dataprepper.logstash.model.LogstashValueType; + +import java.util.UUID; +import java.util.Random; +import java.util.Collections; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.LinkedList; +import java.util.HashMap; +import java.util.LinkedHashMap; + + +public class TestDataProvider { + static final String RANDOM_STRING_1 = UUID.randomUUID().toString(); + static final String RANDOM_STRING_2 = UUID.randomUUID().toString(); + static final String RANDOM_VALUE = String.valueOf(new Random().nextInt(1000)); + + // data + public static LogstashConfiguration configData() { + return LogstashConfiguration.builder().pluginSections(pluginSectionData()).build(); + } + + public static Map> pluginSectionData() { + + List pluginContextList = new LinkedList<>(Collections.singletonList(pluginWithOneArrayContextAttributeData())); + Map> pluginSections = new LinkedHashMap<>(); + pluginSections.put(LogstashPluginType.INPUT, pluginContextList); + + return pluginSections; + } + + public static LogstashPlugin pluginWithNoAttributeData() { + List logstashAttributeList = new LinkedList<>(); + + return LogstashPlugin.builder().pluginName(TestDataProvider.RANDOM_STRING_1).attributes(logstashAttributeList).build(); + } + + public static LogstashPlugin pluginWithOneArrayContextAttributeData() { + List logstashAttributeList = new LinkedList<>(); + logstashAttributeList.add(TestDataProvider.attributeWithArrayTypeValueData()); + + return LogstashPlugin.builder().pluginName(TestDataProvider.RANDOM_STRING_1).attributes(logstashAttributeList).build(); + } + + public static LogstashPlugin pluginWithMorThanOneArrayContextAttributeData() { + List logstashAttributeList = new LinkedList<>(); + logstashAttributeList.add(TestDataProvider.attributeWithArrayTypeValueData()); + logstashAttributeList.add(TestDataProvider.attributeWithArrayTypeValueData()); + + return LogstashPlugin.builder().pluginName(TestDataProvider.RANDOM_STRING_1).attributes(logstashAttributeList).build(); + } + + public static LogstashAttribute attributeWithArrayTypeValueData() { + List values = new LinkedList<>(Arrays.asList(TestDataProvider.RANDOM_STRING_1, TestDataProvider.RANDOM_STRING_2)); + + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). + attributeValueType(LogstashValueType.ARRAY).value(values).build(); + + return LogstashAttribute.builder() + .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + } + + public static LogstashAttribute attributeWithHashTypeValueData() { + Map values = new LinkedHashMap<>(); + values.put(TestDataProvider.RANDOM_STRING_1, TestDataProvider.RANDOM_STRING_2); + + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). + attributeValueType(LogstashValueType.HASH).value(values).build(); + + return LogstashAttribute.builder() + .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + } + + public static LogstashAttribute attributeWithNumberTypeValueData() { + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). + attributeValueType(LogstashValueType.NUMBER).value(Double.valueOf(TestDataProvider.RANDOM_VALUE)).build(); + return LogstashAttribute.builder() + .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + } + + public static LogstashAttribute attributeWithBareWordTypeValueData() { + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). + attributeValueType(LogstashValueType.BAREWORD).value(TestDataProvider.RANDOM_STRING_2).build(); + return LogstashAttribute.builder() + .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + } + + public static LogstashAttribute attributeWithStringTypeValueData() { + LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). + attributeValueType(LogstashValueType.STRING).value(TestDataProvider.RANDOM_STRING_2).build(); + return LogstashAttribute.builder() + .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + } + + public static List arrayData() { + return new LinkedList<>( + Arrays.asList(TestDataProvider.RANDOM_STRING_1, TestDataProvider.RANDOM_STRING_2) + ); + } + + public static Map hashEntryArrayData() { + Map hashentry = new HashMap<>(); + hashentry.put(RANDOM_STRING_1, new LinkedList<>(Arrays.asList(RANDOM_STRING_1, RANDOM_STRING_2))); + + return hashentry; + } + + public static Map hashEntryStringData() { + Map hashentry = new HashMap<>(); + hashentry.put(RANDOM_STRING_1, RANDOM_STRING_2); + + return hashentry; + } + +} \ No newline at end of file From 16e51e8fea8f461f98ad6fe4bfd7602f6f3f83ca Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Mon, 1 Nov 2021 09:52:22 -0400 Subject: [PATCH 2/6] added javadoc for public classes Signed-off-by: Asif Sohail Mohammed --- .../logstash/exception/LogstashConfigurationException.java | 6 ++++++ .../logstash/exception/LogstashGrammarException.java | 6 ++++++ .../logstash/exception/LogstashParsingException.java | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java index bc6b2d3977..0292b964b1 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java @@ -1,5 +1,11 @@ package org.opensearch.dataprepper.logstash.exception; +/** + * Exception for Logtsash converter + * + * @since 1.2 + */ + public class LogstashConfigurationException extends RuntimeException { public LogstashConfigurationException(String errorMessage) { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java index 5c55d726ff..5dad010ab2 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java @@ -1,5 +1,11 @@ package org.opensearch.dataprepper.logstash.exception; +/** + * Exception for ANTLR failures + * + * @since 1.2 + */ + public class LogstashGrammarException extends LogstashParsingException { public LogstashGrammarException(String errorMessage) { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java index b406732fd8..7bb1dcb03f 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java @@ -1,5 +1,11 @@ package org.opensearch.dataprepper.logstash.exception; +/** + * Exception for visitor when it's unable to convert into Logstash models + * + * @since 1.2 + */ + public class LogstashParsingException extends LogstashConfigurationException { public LogstashParsingException(String errorMessage) { From 535b3e255465517c2cffa3dbdb9d23b03f395693 Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Mon, 1 Nov 2021 00:23:45 -0400 Subject: [PATCH 3/6] fixed merge conflicts added logstash visitor populate logstash model POJO's Signed-off-by: Asif Sohail Mohammed --- .../LogstashConfigurationException.java | 3 +- .../exception/LogstashGrammarException.java | 3 +- .../exception/LogstashParsingException.java | 4 +- .../logstash/parser/LogstashVisitor.java | 80 +++++++++---------- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java index 0292b964b1..51f9bc5822 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashConfigurationException.java @@ -1,11 +1,10 @@ package org.opensearch.dataprepper.logstash.exception; /** - * Exception for Logtsash converter + * Exception for Logstash configuration converter * * @since 1.2 */ - public class LogstashConfigurationException extends RuntimeException { public LogstashConfigurationException(String errorMessage) { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java index 5dad010ab2..e135d53741 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashGrammarException.java @@ -1,11 +1,10 @@ package org.opensearch.dataprepper.logstash.exception; /** - * Exception for ANTLR failures + * Exception thrown when ANTLR fails to parse the Logstash configuration * * @since 1.2 */ - public class LogstashGrammarException extends LogstashParsingException { public LogstashGrammarException(String errorMessage) { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java index 7bb1dcb03f..4180a8971b 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java @@ -1,11 +1,11 @@ package org.opensearch.dataprepper.logstash.exception; /** - * Exception for visitor when it's unable to convert into Logstash models + * Exception thrown when {@link org.opensearch.dataprepper.logstash.parser.LogstashVisitor} is unable to convert + * * Logstash configuration into Logstash model objects * * @since 1.2 */ - public class LogstashParsingException extends LogstashConfigurationException { public LogstashParsingException(String errorMessage) { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java index b75f0c397e..2bd1751c33 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java @@ -17,7 +17,7 @@ import java.util.ArrayList; /** - * Class to populate Logstash configuration model POJO's using ANTLR + * Class to populate Logstash configuration model objects using ANTLR * * @since 1.2 */ @@ -30,9 +30,9 @@ public class LogstashVisitor extends LogstashBaseVisitor { private final Map hashEntries = new LinkedHashMap<>(); @Override - public Object visitConfig(LogstashParser.ConfigContext ctx) { - for(int i = 0; i < ctx.plugin_section().size(); i++) { - visitPlugin_section(ctx.plugin_section().get(i)); + public Object visitConfig(LogstashParser.ConfigContext configContext) { + for(int i = 0; i < configContext.plugin_section().size(); i++) { + visitPlugin_section(configContext.plugin_section().get(i)); } return LogstashConfiguration.builder() .pluginSections(pluginSections) @@ -40,12 +40,12 @@ public Object visitConfig(LogstashParser.ConfigContext ctx) { } @Override - public Object visitPlugin_section(LogstashParser.Plugin_sectionContext ctx) { + public Object visitPlugin_section(LogstashParser.Plugin_sectionContext pluginSectionContext) { LogstashPluginType logstashPluginType; logstashPluginList = new LinkedList<>(); - switch (ctx.plugin_type().getText()) { + switch (pluginSectionContext.plugin_type().getText()) { case "input": logstashPluginType = LogstashPluginType.INPUT; break; @@ -59,8 +59,8 @@ public Object visitPlugin_section(LogstashParser.Plugin_sectionContext ctx) { throw new LogstashParsingException("only input, filter and output plugin sections are supported."); } - for (int i = 0; i < ctx.branch_or_plugin().size(); i++) { - logstashPluginList.add((LogstashPlugin) visitBranch_or_plugin(ctx.branch_or_plugin().get(i))); + for (int i = 0; i < pluginSectionContext.branch_or_plugin().size(); i++) { + logstashPluginList.add((LogstashPlugin) visitBranch_or_plugin(pluginSectionContext.branch_or_plugin().get(i))); } pluginSections.put(logstashPluginType, logstashPluginList); @@ -69,10 +69,10 @@ public Object visitPlugin_section(LogstashParser.Plugin_sectionContext ctx) { } @Override - public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext ctx) { + public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext branchOrPluginContext) { - if (ctx.getChild(0) instanceof LogstashParser.PluginContext) { - return visitPlugin(ctx.plugin()); + if (branchOrPluginContext.getChild(0) instanceof LogstashParser.PluginContext) { + return visitPlugin(branchOrPluginContext.plugin()); } else { throw new LogstashParsingException("conditionals are not supported"); @@ -80,12 +80,12 @@ public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext ctx) } @Override - public Object visitPlugin(LogstashParser.PluginContext ctx) { - String pluginName = ctx.name().getText(); + public Object visitPlugin(LogstashParser.PluginContext pluginContext) { + String pluginName = pluginContext.name().getText(); List logstashAttributeList = new ArrayList<>(); - for (int i = 0; i < ctx.attributes().attribute().size(); i++) { - logstashAttributeList.add((LogstashAttribute) visitAttribute(ctx.attributes().attribute().get(i))); + for (int i = 0; i < pluginContext.attributes().attribute().size(); i++) { + logstashAttributeList.add((LogstashAttribute) visitAttribute(pluginContext.attributes().attribute().get(i))); } return LogstashPlugin.builder() @@ -95,33 +95,33 @@ public Object visitPlugin(LogstashParser.PluginContext ctx) { } @Override - public Object visitAttribute(LogstashParser.AttributeContext ctx) { + public Object visitAttribute(LogstashParser.AttributeContext attributeContext) { LogstashValueType logstashValueType = null; Object value = null; - if (ctx.value().getChild(0) instanceof LogstashParser.ArrayContext) { + if (attributeContext.value().getChild(0) instanceof LogstashParser.ArrayContext) { logstashValueType = LogstashValueType.ARRAY; - value = visitArray(ctx.value().array()); + value = visitArray(attributeContext.value().array()); } - else if (ctx.value().getChild(0) instanceof LogstashParser.HashContext) { + else if (attributeContext.value().getChild(0) instanceof LogstashParser.HashContext) { logstashValueType = LogstashValueType.HASH; - value = visitHash(ctx.value().hash()); + value = visitHash(attributeContext.value().hash()); } - else if (ctx.value().getChild(0) instanceof LogstashParser.PluginContext) { + else if (attributeContext.value().getChild(0) instanceof LogstashParser.PluginContext) { throw new LogstashParsingException("plugins are not supported in attribute"); } - else if (ctx.value().NUMBER() != null && ctx.value().getText().equals(ctx.value().NUMBER().toString())) { + else if (attributeContext.value().NUMBER() != null && attributeContext.value().getText().equals(attributeContext.value().NUMBER().toString())) { logstashValueType = LogstashValueType.NUMBER; - value = Double.valueOf(ctx.value().getText()); + value = Double.valueOf(attributeContext.value().getText()); } - else if (ctx.value().BAREWORD() != null && ctx.value().getText().equals(ctx.value().BAREWORD().toString())) { + else if (attributeContext.value().BAREWORD() != null && attributeContext.value().getText().equals(attributeContext.value().BAREWORD().toString())) { logstashValueType = LogstashValueType.BAREWORD; - value = ctx.value().getText(); + value = attributeContext.value().getText(); } - else if (ctx.value().STRING() != null && ctx.value().getText().equals(ctx.value().STRING().toString())) { + else if (attributeContext.value().STRING() != null && attributeContext.value().getText().equals(attributeContext.value().STRING().toString())) { logstashValueType = LogstashValueType.STRING; - value = ctx.value().getText().replaceAll("^\"|\"$|^'|'$", ""); + value = attributeContext.value().getText().replaceAll("^\"|\"$|^'|'$", ""); } LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder() @@ -130,41 +130,41 @@ else if (ctx.value().STRING() != null && ctx.value().getText().equals(ctx.value( .build(); return LogstashAttribute.builder() - .attributeName(ctx.name().getText()) + .attributeName(attributeContext.name().getText()) .attributeValue(logstashAttributeValue) .build(); } @Override - public Object visitArray(LogstashParser.ArrayContext ctx) { + public Object visitArray(LogstashParser.ArrayContext arrayContext) { List values = new LinkedList<>(); - for(int i = 0; i < ctx.value().size(); i++) - values.add(ctx.value().get(i).getText() ); + for(int i = 0; i < arrayContext.value().size(); i++) + values.add(arrayContext.value().get(i).getText() ); return values; } @Override - public Object visitHash(LogstashParser.HashContext ctx) { - return visitHashentries(ctx.hashentries()); + public Object visitHash(LogstashParser.HashContext hashContext) { + return visitHashentries(hashContext.hashentries()); } @Override - public Object visitHashentries(LogstashParser.HashentriesContext ctx) { - for (int i = 0; i < ctx.hashentry().size(); i++) { - visitHashentry((ctx.hashentry().get(i))); + public Object visitHashentries(LogstashParser.HashentriesContext hashentriesContext) { + for (int i = 0; i < hashentriesContext.hashentry().size(); i++) { + visitHashentry((hashentriesContext.hashentry().get(i))); } return hashEntries; } @Override - public Object visitHashentry(LogstashParser.HashentryContext ctx) { + public Object visitHashentry(LogstashParser.HashentryContext hashentryContext) { - if (ctx.value().getChild(0) instanceof LogstashParser.ArrayContext) - hashEntries.put(ctx.hashname().getText(), visitArray(ctx.value().array())); + if (hashentryContext.value().getChild(0) instanceof LogstashParser.ArrayContext) + hashEntries.put(hashentryContext.hashname().getText(), visitArray(hashentryContext.value().array())); else - hashEntries.put(ctx.hashname().getText(), ctx.value().getText()); + hashEntries.put(hashentryContext.hashname().getText(), hashentryContext.value().getText()); return hashEntries; } From 378becd2bc469a5c06dfe513f65c2b8ddc938a86 Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Mon, 1 Nov 2021 14:56:22 -0400 Subject: [PATCH 4/6] fixed merge conflicts updated javadoc for public classes Signed-off-by: Asif Sohail Mohammed --- .../src/main/antlr/Logstash.g4 | 4 ++++ .../dataprepper/logstash/parser/LogstashVisitor.java | 1 - .../dataprepper/logstash/parser/TestDataProvider.java | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 index a3d169ac6d..eb22d50c31 100644 --- a/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 +++ b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 @@ -1,3 +1,7 @@ +/* +* Grammar file for parsing Logstash configurations +*/ + grammar Logstash; @header { diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java index 2bd1751c33..6c36485c36 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java @@ -110,7 +110,6 @@ else if (attributeContext.value().getChild(0) instanceof LogstashParser.HashCont else if (attributeContext.value().getChild(0) instanceof LogstashParser.PluginContext) { throw new LogstashParsingException("plugins are not supported in attribute"); } - else if (attributeContext.value().NUMBER() != null && attributeContext.value().getText().equals(attributeContext.value().NUMBER().toString())) { logstashValueType = LogstashValueType.NUMBER; value = Double.valueOf(attributeContext.value().getText()); diff --git a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java index 35fe0c40e0..bc6217053b 100644 --- a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java +++ b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java @@ -23,7 +23,6 @@ public class TestDataProvider { static final String RANDOM_STRING_2 = UUID.randomUUID().toString(); static final String RANDOM_VALUE = String.valueOf(new Random().nextInt(1000)); - // data public static LogstashConfiguration configData() { return LogstashConfiguration.builder().pluginSections(pluginSectionData()).build(); } From 6b086c92cf8c177e75fb877c5f2d44bfc567567d Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Thu, 4 Nov 2021 00:44:13 -0400 Subject: [PATCH 5/6] updated grammar and visitor to use streams. Removed redundant mocking Signed-off-by: Asif Sohail Mohammed --- .../src/main/antlr/Logstash.g4 | 9 +- .../exception/LogstashParsingException.java | 3 +- .../logstash/model/LogstashPluginType.java | 29 +- .../logstash/parser/LogstashVisitor.java | 102 +++----- .../logstash/parser/LogstashVisitorTest.java | 247 ++++++------------ .../logstash/parser/TestDataProvider.java | 36 ++- 6 files changed, 176 insertions(+), 250 deletions(-) diff --git a/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 index eb22d50c31..5d7ca79271 100644 --- a/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 +++ b/data-prepper-logstash-configuration/src/main/antlr/Logstash.g4 @@ -1,7 +1,6 @@ /* -* Grammar file for parsing Logstash configurations +* ANTLR grammar file for parsing Logstash configurations */ - grammar Logstash; @header { @@ -94,7 +93,7 @@ not_in_expression: rvalue filler not_in_operator filler rvalue; rvalue: STRING | NUMBER | selector | array | method_call | regexp; -regexp: '/' ('^' | '\\' | '.' | '+' |.)*? '/'; +regexp: '/' ('\\' | ~'/' .)*? '/'; selector: selector_element+; @@ -127,7 +126,7 @@ COMMENT: (WS? '#' ~('\r'|'\n')*)+; NEWLINE: ('\r'? '\n' | '\r')+ -> skip; -WS: ( NEWLINE | ' ' | '\t' | '\r')+; +WS: ( NEWLINE | ' ' | '\t')+; fragment DIGIT: [0-9]; @@ -139,4 +138,4 @@ STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING; fragment DOUBLE_QUOTED_STRING : ('"' ( '\\"' | . )*? '"'); -fragment SINGLE_QUOTED_STRING : ('\'' ( . )*? '\''); \ No newline at end of file +fragment SINGLE_QUOTED_STRING : ('\'' ('\'' | . )*? '\''); \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java index 4180a8971b..cd34b6c3ce 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/exception/LogstashParsingException.java @@ -1,8 +1,7 @@ package org.opensearch.dataprepper.logstash.exception; /** - * Exception thrown when {@link org.opensearch.dataprepper.logstash.parser.LogstashVisitor} is unable to convert - * * Logstash configuration into Logstash model objects + * Exception thrown when ANTLR visitor is unable to convert Logstash configuration into Logstash model objects * * @since 1.2 */ diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/model/LogstashPluginType.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/model/LogstashPluginType.java index c519c4e8f9..1a6bd55c83 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/model/LogstashPluginType.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/model/LogstashPluginType.java @@ -1,12 +1,35 @@ package org.opensearch.dataprepper.logstash.model; +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + /** * Types of plugins in Logstash configuration * * @since 1.2 */ public enum LogstashPluginType { - INPUT, - FILTER, - OUTPUT + INPUT("input"), + FILTER("filter"), + OUTPUT("output"); + + private final String value; + + private static final Map VALUES_MAP = Arrays.stream(LogstashPluginType.values()) + .collect(Collectors.toMap(LogstashPluginType::toString, Function.identity())); + + LogstashPluginType(final String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + + public static LogstashPluginType getByValue(final String value) { + return VALUES_MAP.get(value.toLowerCase()); + } } diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java index 6c36485c36..f100953244 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java @@ -1,5 +1,6 @@ package org.opensearch.dataprepper.logstash.parser; +import org.antlr.v4.runtime.RuleContext; import org.opensearch.dataprepper.logstash.exception.LogstashParsingException; import org.opensearch.dataprepper.logstash.LogstashBaseVisitor; import org.opensearch.dataprepper.logstash.LogstashParser; @@ -10,30 +11,33 @@ import org.opensearch.dataprepper.logstash.model.LogstashPluginType; import org.opensearch.dataprepper.logstash.model.LogstashValueType; -import java.util.LinkedHashMap; +import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.LinkedList; -import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.stream.Collectors; /** - * Class to populate Logstash configuration model objects using ANTLR + * Class to populate Logstash configuration model objects using ANTLR library classes and generated code. * * @since 1.2 */ - @SuppressWarnings("rawtypes") -public class LogstashVisitor extends LogstashBaseVisitor { - - private List logstashPluginList; - private final Map> pluginSections = new LinkedHashMap<>(); - private final Map hashEntries = new LinkedHashMap<>(); +class LogstashVisitor extends LogstashBaseVisitor { @Override public Object visitConfig(LogstashParser.ConfigContext configContext) { - for(int i = 0; i < configContext.plugin_section().size(); i++) { - visitPlugin_section(configContext.plugin_section().get(i)); - } + final Map> pluginSections = new LinkedHashMap<>(); + + configContext.plugin_section().forEach(pluginSection -> { + final String pluginType = pluginSection.plugin_type().getText(); + if (!Arrays.asList(new String[]{"input", "filter", "output"}).contains(pluginType)) + throw new LogstashParsingException("only input, filter and output plugin sections are supported."); + final LogstashPluginType logstashPluginType = LogstashPluginType.getByValue(pluginType); + final List logstashPluginList = (List) visitPlugin_section(pluginSection); + pluginSections.put(logstashPluginType, logstashPluginList); + }); + return LogstashConfiguration.builder() .pluginSections(pluginSections) .build(); @@ -42,51 +46,26 @@ public Object visitConfig(LogstashParser.ConfigContext configContext) { @Override public Object visitPlugin_section(LogstashParser.Plugin_sectionContext pluginSectionContext) { - LogstashPluginType logstashPluginType; - logstashPluginList = new LinkedList<>(); - - switch (pluginSectionContext.plugin_type().getText()) { - case "input": - logstashPluginType = LogstashPluginType.INPUT; - break; - case "filter": - logstashPluginType = LogstashPluginType.FILTER; - break; - case "output": - logstashPluginType = LogstashPluginType.OUTPUT; - break; - default: - throw new LogstashParsingException("only input, filter and output plugin sections are supported."); - } - - for (int i = 0; i < pluginSectionContext.branch_or_plugin().size(); i++) { - logstashPluginList.add((LogstashPlugin) visitBranch_or_plugin(pluginSectionContext.branch_or_plugin().get(i))); - } - - pluginSections.put(logstashPluginType, logstashPluginList); - - return pluginSections; + return pluginSectionContext.branch_or_plugin().stream() + .map(this::visitBranch_or_plugin) + .collect(Collectors.toList()); } @Override public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext branchOrPluginContext) { - if (branchOrPluginContext.getChild(0) instanceof LogstashParser.PluginContext) { + if (branchOrPluginContext.getChild(0) instanceof LogstashParser.PluginContext) return visitPlugin(branchOrPluginContext.plugin()); - } - else { + else throw new LogstashParsingException("conditionals are not supported"); - } } @Override public Object visitPlugin(LogstashParser.PluginContext pluginContext) { - String pluginName = pluginContext.name().getText(); - List logstashAttributeList = new ArrayList<>(); - - for (int i = 0; i < pluginContext.attributes().attribute().size(); i++) { - logstashAttributeList.add((LogstashAttribute) visitAttribute(pluginContext.attributes().attribute().get(i))); - } + final String pluginName = pluginContext.name().getText(); + final List logstashAttributeList = pluginContext.attributes().attribute().stream() + .map(attribute -> (LogstashAttribute) visitAttribute(attribute)) + .collect(Collectors.toList()); return LogstashPlugin.builder() .pluginName(pluginName) @@ -108,7 +87,7 @@ else if (attributeContext.value().getChild(0) instanceof LogstashParser.HashCont value = visitHash(attributeContext.value().hash()); } else if (attributeContext.value().getChild(0) instanceof LogstashParser.PluginContext) { - throw new LogstashParsingException("plugins are not supported in attribute"); + throw new LogstashParsingException("plugins are not supported in an attribute"); } else if (attributeContext.value().NUMBER() != null && attributeContext.value().getText().equals(attributeContext.value().NUMBER().toString())) { logstashValueType = LogstashValueType.NUMBER; @@ -136,11 +115,9 @@ else if (attributeContext.value().STRING() != null && attributeContext.value().g @Override public Object visitArray(LogstashParser.ArrayContext arrayContext) { - List values = new LinkedList<>(); - - for(int i = 0; i < arrayContext.value().size(); i++) - values.add(arrayContext.value().get(i).getText() ); - return values; + return arrayContext.value().stream() + .map(RuleContext::getText) + .collect(Collectors.toList()); } @Override @@ -150,21 +127,22 @@ public Object visitHash(LogstashParser.HashContext hashContext) { @Override public Object visitHashentries(LogstashParser.HashentriesContext hashentriesContext) { - for (int i = 0; i < hashentriesContext.hashentry().size(); i++) { - visitHashentry((hashentriesContext.hashentry().get(i))); - } + final Map hashEntries = new LinkedHashMap<>(); + + hashentriesContext.hashentry().forEach(hashentryContext -> { + final String key = hashentryContext.hashname().getText(); + final Object value = visitHashentry(hashentryContext); + hashEntries.put(key, value); + }); + return hashEntries; } @Override public Object visitHashentry(LogstashParser.HashentryContext hashentryContext) { - if (hashentryContext.value().getChild(0) instanceof LogstashParser.ArrayContext) - hashEntries.put(hashentryContext.hashname().getText(), visitArray(hashentryContext.value().array())); + return visitArray(hashentryContext.value().array()); - else - hashEntries.put(hashentryContext.hashname().getText(), hashentryContext.value().getText()); - - return hashEntries; + return hashentryContext.value().getText(); } } \ No newline at end of file diff --git a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java index 5446a2b6da..a8e6011f13 100644 --- a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java +++ b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitorTest.java @@ -1,6 +1,7 @@ package org.opensearch.dataprepper.logstash.parser; import org.antlr.v4.runtime.tree.TerminalNodeImpl; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -9,6 +10,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.mock; +import org.mockito.Mock; import org.mockito.Mockito; import org.opensearch.dataprepper.logstash.LogstashParser; import org.opensearch.dataprepper.logstash.exception.LogstashParsingException; @@ -21,27 +23,61 @@ import java.util.Arrays; import java.util.List; import java.util.LinkedList; -import java.util.Map; class LogstashVisitorTest { - private LogstashVisitor createObjectUnderTest() { - return spy(new LogstashVisitor()); + private static LogstashVisitor logstashVisitor; + + @BeforeEach + void createObjectUnderTest() { + logstashVisitor = spy(new LogstashVisitor()); } - @Test - void visit_config_test() { - final LogstashParser.ConfigContext configContextMock = mock(LogstashParser.ConfigContext.class); - final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); - final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); - final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + @Mock + private LogstashParser.ConfigContext configContextMock = mock(LogstashParser.ConfigContext.class); + @Mock + private LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); + @Mock + private LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); + @Mock + private LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); + @Mock + private LogstashParser.BranchContext branchContextMock = mock(LogstashParser.BranchContext.class); + @Mock + private LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); + @Mock + private LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); + @Mock + private LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); + @Mock + private LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); + @Mock + private LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); + @Mock + private LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); + @Mock + private LogstashParser.ValueContext arrayValueContextMock1 = mock(LogstashParser.ValueContext.class); + @Mock + private LogstashParser.ValueContext arrayValueContextMock2 = mock(LogstashParser.ValueContext.class); + @Mock + private LogstashParser.HashContext hashContextMock = mock(LogstashParser.HashContext.class); + @Mock + private LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); + @Mock + private TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); + @Mock + private LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); + @Mock + private LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); + + @Test + void visit_config_return_logstash_configuration_object_test() { given(configContextMock.plugin_section()).willReturn(Collections.singletonList(pluginSectionMock)); given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); given(pluginTypeContextMock.getText()).willReturn("input"); given(pluginSectionMock.branch_or_plugin()).willReturn(Collections.singletonList(branchOrPluginContextMock)); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.pluginWithOneArrayContextAttributeData()).when(logstashVisitor).visitBranch_or_plugin(branchOrPluginContextMock); LogstashConfiguration actualLogstashConfiguration = (LogstashConfiguration) logstashVisitor.visitConfig(configContextMock); @@ -52,14 +88,8 @@ void visit_config_test() { Mockito.verify(logstashVisitor, Mockito.times(1)).visitPlugin_section(pluginSectionMock); } - @SuppressWarnings("unchecked") @Test void visit_plugin_section_test() { - final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); - final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); - final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); given(pluginTypeContextMock.getText()).willReturn("input"); @@ -70,30 +100,27 @@ void visit_plugin_section_test() { given(branchOrPluginContextMock.getChild(0)).willReturn(pluginContextMock); given(branchOrPluginContextMock.plugin()).willReturn(pluginContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.pluginWithOneArrayContextAttributeData()).when(logstashVisitor).visitPlugin(pluginContextMock); - Map> actualPluginSections = (Map>) - logstashVisitor.visitPlugin_section(pluginSectionMock); - Map> expectedPluginSections = TestDataProvider.pluginSectionData(); + List actualPluginSections = (List) logstashVisitor.visitPlugin_section(pluginSectionMock); + List expectedPluginSections = TestDataProvider.pluginSectionData(); + + System.out.println(actualPluginSections); + System.out.println(expectedPluginSections); - assertThat(actualPluginSections.keySet(), equalTo(expectedPluginSections.keySet())); - assertThat(actualPluginSections.get(LogstashPluginType.INPUT).size(), - equalTo(expectedPluginSections.get(LogstashPluginType.INPUT).size())); + assertThat(actualPluginSections.size(), equalTo(expectedPluginSections.size())); + for (int i = 0; i < expectedPluginSections.size(); i++) + assertThat(actualPluginSections.get(i).getPluginName(), equalTo(expectedPluginSections.get(i).getPluginName())); } @Test - void visit_plugin_section_with_unsupported_section_name_throws_logstash_parsing_exception_test() { - final LogstashParser.Plugin_sectionContext pluginSectionMock = mock(LogstashParser.Plugin_sectionContext.class); - final LogstashParser.Plugin_typeContext pluginTypeContextMock = mock(LogstashParser.Plugin_typeContext.class); - + void visit_config_with_unsupported_section_name_throws_logstash_parsing_exception_test() { + given(configContextMock.plugin_section()).willReturn(Collections.singletonList(pluginSectionMock)); given(pluginSectionMock.plugin_type()).willReturn(pluginTypeContextMock); given(pluginTypeContextMock.getText()).willReturn("inputt"); - LogstashVisitor logstashVisitor = createObjectUnderTest(); - Exception exception = assertThrows(LogstashParsingException.class, () -> - logstashVisitor.visitPlugin_section(pluginSectionMock)); + logstashVisitor.visitConfig(configContextMock)); String expectedMessage = "only input, filter and output plugin sections are supported."; String actualMessage = exception.getMessage(); @@ -103,13 +130,8 @@ void visit_plugin_section_with_unsupported_section_name_throws_logstash_parsing_ @Test void visit_branch_or_plugin_with_branch_throws_logstash_parsing_exception_test() { - final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); - final LogstashParser.BranchContext branchContextMock = mock(LogstashParser.BranchContext.class); - given(branchOrPluginContextMock.getChild(0)).willReturn(branchContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); - Exception exception = assertThrows(LogstashParsingException.class, () -> logstashVisitor.visitBranch_or_plugin(branchOrPluginContextMock)); @@ -121,12 +143,6 @@ void visit_branch_or_plugin_with_branch_throws_logstash_parsing_exception_test() @Test void visit_branch_or_plugin_returns_logstash_plugin_test() { - final LogstashParser.Branch_or_pluginContext branchOrPluginContextMock = mock(LogstashParser.Branch_or_pluginContext.class); - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - given(branchOrPluginContextMock.getChild(0)).willReturn(pluginContextMock); given(branchOrPluginContextMock.plugin()).willReturn(pluginContextMock); given(pluginContextMock.name()).willReturn(nameContextMock); @@ -137,7 +153,6 @@ void visit_branch_or_plugin_returns_logstash_plugin_test() { given(pluginContextMock.attributes()).willReturn(attributesContextMock); given(attributesContextMock.attribute()).willReturn(attributeContexts); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.attributeWithArrayTypeValueData()).when(logstashVisitor).visitAttribute(attributeContextMock); LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitBranch_or_plugin(branchOrPluginContextMock); @@ -157,16 +172,10 @@ void visit_branch_or_plugin_returns_logstash_plugin_test() { @Test void visit_plugin_with_no_attribute_test() { - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - given(pluginContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(pluginContextMock.attributes()).willReturn(attributesContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); @@ -178,13 +187,6 @@ void visit_plugin_with_no_attribute_test() { @Test void visit_plugin_with_one_array_context_attribute_test() { - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - given(pluginContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(pluginContextMock.attributes()).willReturn(attributesContextMock); @@ -198,7 +200,6 @@ void visit_plugin_with_one_array_context_attribute_test() { given(valueContextMock.getChild(0)).willReturn(arrayContextMock); given(valueContextMock.array()).willReturn(arrayContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); @@ -220,13 +221,6 @@ void visit_plugin_with_one_array_context_attribute_test() { @Test void visit_plugin_with_more_than_one_array_context_attribute_test() { - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.AttributesContext attributesContextMock = mock(LogstashParser.AttributesContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - given(pluginContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(pluginContextMock.attributes()).willReturn(attributesContextMock); @@ -242,7 +236,6 @@ void visit_plugin_with_more_than_one_array_context_attribute_test() { given(valueContextMock.getChild(0)).willReturn(arrayContextMock); given(valueContextMock.array()).willReturn(arrayContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); LogstashPlugin actualLogstashPlugin = (LogstashPlugin) logstashVisitor.visitPlugin(pluginContextMock); @@ -264,26 +257,18 @@ void visit_plugin_with_more_than_one_array_context_attribute_test() { @Test void visit_attribute_with_value_type_array_returns_correct_logstash_attribute_test() { - - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); - final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); - given(attributeContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(attributeContextMock.value()).willReturn(valueContextMock); given(valueContextMock.getChild(0)).willReturn(arrayContextMock); given(valueContextMock.array()).willReturn(arrayContextMock); - List valueContextList = new LinkedList<>(Arrays.asList(valueContextMock1, valueContextMock2)); + List valueContextList = new LinkedList<>(Arrays.asList(arrayValueContextMock1, arrayValueContextMock2)); given(arrayContextMock.value()).willReturn(valueContextList); - given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); - given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + given(arrayValueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(arrayValueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); - LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithArrayTypeValueData(); assertThat(actualLogstashAttribute.getAttributeName(), @@ -296,12 +281,6 @@ void visit_attribute_with_value_type_array_returns_correct_logstash_attribute_te @Test void visit_attribute_with_value_type_hash_returns_correct_logstash_attribute_test() { - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); - final LogstashParser.HashContext hashContextMock = mock(LogstashParser.HashContext.class); - given(attributeContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(attributeContextMock.value()).willReturn(valueContextMock); @@ -309,8 +288,7 @@ void visit_attribute_with_value_type_hash_returns_correct_logstash_attribute_tes given(valueContextMock.hash()).willReturn(hashContextMock); given(hashContextMock.hashentries()).willReturn(hashentriesContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); - Mockito.doReturn(TestDataProvider.hashEntryStringData()).when(logstashVisitor).visitHashentries(hashentriesContextMock); + Mockito.doReturn(TestDataProvider.hashEntriesStringData()).when(logstashVisitor).visitHashentries(hashentriesContextMock); LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithHashTypeValueData(); @@ -325,19 +303,12 @@ void visit_attribute_with_value_type_hash_returns_correct_logstash_attribute_tes @Test void visit_attribute_with_value_type_plugin_throws_logstash_parsing_exception_test() { - - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.PluginContext pluginContextMock = mock(LogstashParser.PluginContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - given(attributeContextMock.value()).willReturn(valueContextMock); given(valueContextMock.getChild(0)).willReturn(pluginContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); - Exception exception = assertThrows(LogstashParsingException.class, () -> logstashVisitor.visitAttribute(attributeContextMock)); - String expectedMessage = "plugins are not supported in attribute"; + String expectedMessage = "plugins are not supported in an attribute"; String actualMessage = exception.getMessage(); assertThat(expectedMessage, equalTo(actualMessage)); @@ -345,11 +316,6 @@ void visit_attribute_with_value_type_plugin_throws_logstash_parsing_exception_te @Test void visit_attribute_with_value_type_number_returns_correct_logstash_attribute_test() { - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); - given(attributeContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(attributeContextMock.value()).willReturn(valueContextMock); @@ -357,7 +323,7 @@ void visit_attribute_with_value_type_number_returns_correct_logstash_attribute_t given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_VALUE); given(valueContextMock.NUMBER().toString()).willReturn(TestDataProvider.RANDOM_VALUE); - LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithNumberTypeValueData(); assertThat(actualLogstashAttribute.getAttributeName(), @@ -370,11 +336,6 @@ void visit_attribute_with_value_type_number_returns_correct_logstash_attribute_t @Test void visit_attribute_with_value_type_bare_word_returns_correct_logstash_attribute_test() { - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); - given(attributeContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(attributeContextMock.value()).willReturn(valueContextMock); @@ -382,7 +343,7 @@ void visit_attribute_with_value_type_bare_word_returns_correct_logstash_attribut given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); given(valueContextMock.BAREWORD().toString()).willReturn(TestDataProvider.RANDOM_STRING_2); - LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithBareWordTypeValueData(); @@ -397,11 +358,6 @@ void visit_attribute_with_value_type_bare_word_returns_correct_logstash_attribut @Test void visit_attribute_with_value_type_string_returns_correct_logstash_attribute_test() { - final LogstashParser.AttributeContext attributeContextMock = mock(LogstashParser.AttributeContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.NameContext nameContextMock = mock(LogstashParser.NameContext.class); - final TerminalNodeImpl terminalNodeMock = mock(TerminalNodeImpl.class); - given(attributeContextMock.name()).willReturn(nameContextMock); given(nameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(attributeContextMock.value()).willReturn(valueContextMock); @@ -409,7 +365,7 @@ void visit_attribute_with_value_type_string_returns_correct_logstash_attribute_t given(valueContextMock.getText()).willReturn("\"" + TestDataProvider.RANDOM_STRING_2 + "\""); given(valueContextMock.STRING().toString()).willReturn("\"" + TestDataProvider.RANDOM_STRING_2 + "\""); - LogstashAttribute actualLogstashAttribute = (LogstashAttribute) createObjectUnderTest().visitAttribute(attributeContextMock); + LogstashAttribute actualLogstashAttribute = (LogstashAttribute) logstashVisitor.visitAttribute(attributeContextMock); LogstashAttribute expectedLogstashAttribute = TestDataProvider.attributeWithStringTypeValueData(); assertThat(actualLogstashAttribute.getAttributeName(), @@ -423,54 +379,37 @@ void visit_attribute_with_value_type_string_returns_correct_logstash_attribute_t @Test void visit_array_with_empty_array_returns_empty_list_test() { - - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - given(arrayContextMock.value()).willReturn(Collections.emptyList()); - - Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + Object actualList = logstashVisitor.visitArray(arrayContextMock); assertThat(actualList, equalTo(Collections.emptyList())); } @Test void visit_array_with_singleton_array_returns_list_df_size_one_test() { - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(arrayContextMock.value()).willReturn(Collections.singletonList(valueContextMock)); - Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + Object actualList = logstashVisitor.visitArray(arrayContextMock); assertThat(actualList, equalTo(Collections.singletonList(TestDataProvider.RANDOM_STRING_1))); } @Test void visit_array_with_array_of_size_more_than_one_returns_list_of_size_more_than_one_test() { - LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); - final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); - - List valueContextList = new LinkedList<>(Arrays.asList(valueContextMock1, valueContextMock2)); + List valueContextList = new LinkedList<>(Arrays.asList(arrayValueContextMock1, arrayValueContextMock2)); given(arrayContextMock.value()).willReturn(valueContextList); - given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); - given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + given(arrayValueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(arrayValueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); - Object actualList = createObjectUnderTest().visitArray(arrayContextMock); + Object actualList = logstashVisitor.visitArray(arrayContextMock); assertThat(actualList, equalTo(TestDataProvider.arrayData())); } @Test void visit_hash_entries_with_string_value_returns_map_of_hash_entries_test() { - - final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); - final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); - List hashentryContextList = new LinkedList<>( Collections.singletonList(hashentryContextMock)); @@ -480,20 +419,13 @@ void visit_hash_entries_with_string_value_returns_map_of_hash_entries_test() { given(hashentryContextMock.value()).willReturn(valueContextMock); given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); - Object actualMap = createObjectUnderTest().visitHashentries(hashentriesContextMock); + Object actualMap = logstashVisitor.visitHashentries(hashentriesContextMock); - assertThat(actualMap, equalTo(TestDataProvider.hashEntryStringData())); + assertThat(actualMap, equalTo(TestDataProvider.hashEntriesStringData())); } @Test void visit_hash_entries_with_array_value_returns_map_of_hash_entries_test() { - - final LogstashParser.HashentriesContext hashentriesContextMock = mock(LogstashParser.HashentriesContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); - final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - List hashentryContextList = new LinkedList<>( Collections.singletonList(hashentryContextMock)); @@ -504,54 +436,39 @@ void visit_hash_entries_with_array_value_returns_map_of_hash_entries_test() { given(hashentryContextMock.value().getChild(0)).willReturn(arrayContextMock); given(valueContextMock.array()).willReturn(arrayContextMock); - LogstashVisitor logstashVisitor = createObjectUnderTest(); Mockito.doReturn(TestDataProvider.arrayData()).when(logstashVisitor).visitArray(arrayContextMock); Object actualMap = logstashVisitor.visitHashentries(hashentriesContextMock); + Object expectedMap = TestDataProvider.hashEntriesArrayData(); - assertThat(actualMap, equalTo(TestDataProvider.hashEntryArrayData())); + + assertThat(actualMap, equalTo(expectedMap)); } @Test void visit_hash_entry_with_value_type_string_returns_string_object_test() { - final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); - final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - - given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); - given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(hashentryContextMock.value()).willReturn(valueContextMock); given(valueContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); - Object actualValue = createObjectUnderTest().visitHashentry(hashentryContextMock); + Object actualValue = logstashVisitor.visitHashentry(hashentryContextMock); assertThat(actualValue, equalTo(TestDataProvider.hashEntryStringData())); } @Test void visit_hash_entry_with_array_value_type_returns_list_test() { - - final LogstashParser.HashentryContext hashentryContextMock = mock(LogstashParser.HashentryContext.class); - final LogstashParser.HashnameContext hashnameContextMock = mock(LogstashParser.HashnameContext.class); - final LogstashParser.ValueContext valueContextMock = mock(LogstashParser.ValueContext.class); - final LogstashParser.ArrayContext arrayContextMock = mock(LogstashParser.ArrayContext.class); - final LogstashParser.ValueContext valueContextMock1 = mock(LogstashParser.ValueContext.class); - final LogstashParser.ValueContext valueContextMock2 = mock(LogstashParser.ValueContext.class); - final List linkedListValuesMock = new LinkedList<>( - Arrays.asList(valueContextMock1, valueContextMock2) + Arrays.asList(arrayValueContextMock1, arrayValueContextMock2) ); - given(hashentryContextMock.hashname()).willReturn(hashnameContextMock); - given(hashnameContextMock.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); given(hashentryContextMock.value()).willReturn(valueContextMock); given(hashentryContextMock.value().getChild(0)).willReturn(arrayContextMock); given(valueContextMock.array()).willReturn(arrayContextMock); given(arrayContextMock.value()).willReturn(linkedListValuesMock); - given(valueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); - given(valueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); + given(arrayValueContextMock1.getText()).willReturn(TestDataProvider.RANDOM_STRING_1); + given(arrayValueContextMock2.getText()).willReturn(TestDataProvider.RANDOM_STRING_2); - Object actualList = createObjectUnderTest().visitHashentry(hashentryContextMock); + Object actualList = logstashVisitor.visitHashentry(hashentryContextMock); assertThat(actualList, equalTo(TestDataProvider.hashEntryArrayData())); } diff --git a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java index bc6217053b..4354865a85 100644 --- a/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java +++ b/data-prepper-logstash-configuration/src/test/java/org/opensearch/dataprepper/logstash/parser/TestDataProvider.java @@ -18,22 +18,26 @@ import java.util.LinkedHashMap; -public class TestDataProvider { +class TestDataProvider { static final String RANDOM_STRING_1 = UUID.randomUUID().toString(); static final String RANDOM_STRING_2 = UUID.randomUUID().toString(); static final String RANDOM_VALUE = String.valueOf(new Random().nextInt(1000)); public static LogstashConfiguration configData() { - return LogstashConfiguration.builder().pluginSections(pluginSectionData()).build(); + List pluginContextList = new LinkedList<>(Collections.singletonList(pluginWithOneArrayContextAttributeData())); + Map> pluginSections = new LinkedHashMap<>(); + pluginSections.put(LogstashPluginType.INPUT, pluginContextList); + + return LogstashConfiguration.builder().pluginSections(pluginSections).build(); } - public static Map> pluginSectionData() { + public static List pluginSectionData() { List pluginContextList = new LinkedList<>(Collections.singletonList(pluginWithOneArrayContextAttributeData())); Map> pluginSections = new LinkedHashMap<>(); pluginSections.put(LogstashPluginType.INPUT, pluginContextList); - return pluginSections; + return pluginContextList; } public static LogstashPlugin pluginWithNoAttributeData() { @@ -87,36 +91,42 @@ public static LogstashAttribute attributeWithNumberTypeValueData() { public static LogstashAttribute attributeWithBareWordTypeValueData() { LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). - attributeValueType(LogstashValueType.BAREWORD).value(TestDataProvider.RANDOM_STRING_2).build(); + attributeValueType(LogstashValueType.BAREWORD).value(RANDOM_STRING_2).build(); return LogstashAttribute.builder() - .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + .attributeName(RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); } public static LogstashAttribute attributeWithStringTypeValueData() { LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder(). - attributeValueType(LogstashValueType.STRING).value(TestDataProvider.RANDOM_STRING_2).build(); + attributeValueType(LogstashValueType.STRING).value(RANDOM_STRING_2).build(); return LogstashAttribute.builder() - .attributeName(TestDataProvider.RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); + .attributeName(RANDOM_STRING_1).attributeValue(logstashAttributeValue).build(); } public static List arrayData() { - return new LinkedList<>( - Arrays.asList(TestDataProvider.RANDOM_STRING_1, TestDataProvider.RANDOM_STRING_2) - ); + return Arrays.asList(RANDOM_STRING_1, RANDOM_STRING_2); } - public static Map hashEntryArrayData() { + public static Map hashEntriesArrayData() { Map hashentry = new HashMap<>(); hashentry.put(RANDOM_STRING_1, new LinkedList<>(Arrays.asList(RANDOM_STRING_1, RANDOM_STRING_2))); return hashentry; } - public static Map hashEntryStringData() { + public static Map hashEntriesStringData() { Map hashentry = new HashMap<>(); hashentry.put(RANDOM_STRING_1, RANDOM_STRING_2); return hashentry; } + public static List hashEntryArrayData() { + return Arrays.asList(RANDOM_STRING_1, RANDOM_STRING_2); + } + + public static String hashEntryStringData() { + return RANDOM_STRING_2; + } + } \ No newline at end of file From 3d006ec6a62f56202741a7860291e9d5172a2173 Mon Sep 17 00:00:00 2001 From: Asif Sohail Mohammed Date: Fri, 5 Nov 2021 08:54:55 -0400 Subject: [PATCH 6/6] updated visitor parameters to final. Signed-off-by: Asif Sohail Mohammed --- .../logstash/parser/LogstashVisitor.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java index f100953244..9cc6f4c8dc 100644 --- a/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java +++ b/data-prepper-logstash-configuration/src/main/java/org/opensearch/dataprepper/logstash/parser/LogstashVisitor.java @@ -26,7 +26,7 @@ class LogstashVisitor extends LogstashBaseVisitor { @Override - public Object visitConfig(LogstashParser.ConfigContext configContext) { + public Object visitConfig(final LogstashParser.ConfigContext configContext) { final Map> pluginSections = new LinkedHashMap<>(); configContext.plugin_section().forEach(pluginSection -> { @@ -44,7 +44,7 @@ public Object visitConfig(LogstashParser.ConfigContext configContext) { } @Override - public Object visitPlugin_section(LogstashParser.Plugin_sectionContext pluginSectionContext) { + public Object visitPlugin_section(final LogstashParser.Plugin_sectionContext pluginSectionContext) { return pluginSectionContext.branch_or_plugin().stream() .map(this::visitBranch_or_plugin) @@ -52,7 +52,7 @@ public Object visitPlugin_section(LogstashParser.Plugin_sectionContext pluginSec } @Override - public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext branchOrPluginContext) { + public Object visitBranch_or_plugin(final LogstashParser.Branch_or_pluginContext branchOrPluginContext) { if (branchOrPluginContext.getChild(0) instanceof LogstashParser.PluginContext) return visitPlugin(branchOrPluginContext.plugin()); @@ -61,7 +61,7 @@ public Object visitBranch_or_plugin(LogstashParser.Branch_or_pluginContext branc } @Override - public Object visitPlugin(LogstashParser.PluginContext pluginContext) { + public Object visitPlugin(final LogstashParser.PluginContext pluginContext) { final String pluginName = pluginContext.name().getText(); final List logstashAttributeList = pluginContext.attributes().attribute().stream() .map(attribute -> (LogstashAttribute) visitAttribute(attribute)) @@ -74,7 +74,7 @@ public Object visitPlugin(LogstashParser.PluginContext pluginContext) { } @Override - public Object visitAttribute(LogstashParser.AttributeContext attributeContext) { + public Object visitAttribute(final LogstashParser.AttributeContext attributeContext) { LogstashValueType logstashValueType = null; Object value = null; @@ -102,7 +102,7 @@ else if (attributeContext.value().STRING() != null && attributeContext.value().g value = attributeContext.value().getText().replaceAll("^\"|\"$|^'|'$", ""); } - LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder() + final LogstashAttributeValue logstashAttributeValue = LogstashAttributeValue.builder() .attributeValueType(logstashValueType) .value(value) .build(); @@ -114,19 +114,19 @@ else if (attributeContext.value().STRING() != null && attributeContext.value().g } @Override - public Object visitArray(LogstashParser.ArrayContext arrayContext) { + public Object visitArray(final LogstashParser.ArrayContext arrayContext) { return arrayContext.value().stream() .map(RuleContext::getText) .collect(Collectors.toList()); } @Override - public Object visitHash(LogstashParser.HashContext hashContext) { + public Object visitHash(final LogstashParser.HashContext hashContext) { return visitHashentries(hashContext.hashentries()); } @Override - public Object visitHashentries(LogstashParser.HashentriesContext hashentriesContext) { + public Object visitHashentries(final LogstashParser.HashentriesContext hashentriesContext) { final Map hashEntries = new LinkedHashMap<>(); hashentriesContext.hashentry().forEach(hashentryContext -> { @@ -139,7 +139,7 @@ public Object visitHashentries(LogstashParser.HashentriesContext hashentriesCont } @Override - public Object visitHashentry(LogstashParser.HashentryContext hashentryContext) { + public Object visitHashentry(final LogstashParser.HashentryContext hashentryContext) { if (hashentryContext.value().getChild(0) instanceof LogstashParser.ArrayContext) return visitArray(hashentryContext.value().array());