Skip to content

Commit 7a918e9

Browse files
committed
lir: inject newline delimiter only when necessary
Our internal representation of the composite config file needs only to inject newline delimiters if they are missing, and to avoid doing so if they are present. This allows `PipelineConfig#sourceReferences()`, used to map back from the composite line/column to source file/column, to correctly track an offset using the source fragments `SourceWithMetadata#getLinesCount()`. Fixes: elastic#12155
1 parent 179b0ef commit 7a918e9

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

logstash-core/src/main/java/org/logstash/config/ir/PipelineConfig.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ boolean includeLine(int lineNumber) {
6262
private volatile String configString;
6363
private List<LineToSource> sourceRefs;
6464

65+
private static final String NEWLINE = "\n";
66+
6567
@SuppressWarnings({"rawtypes", "unchecked"})
6668
public PipelineConfig(RubyClass source, RubySymbol pipelineId, RubyObject uncastedConfigParts, RubyObject logstashSettings) {
6769
IRubyObject uncasted = uncastedConfigParts.checkArrayType();
@@ -111,9 +113,16 @@ public String configString() {
111113
if (this.configString == null) {
112114
synchronized(this) {
113115
if (this.configString == null) {
114-
this.configString = confParts.stream()
115-
.map(SourceWithMetadata::getText)
116-
.collect(Collectors.joining("\n"));
116+
final StringBuilder compositeConfig = new StringBuilder();
117+
for (SourceWithMetadata confPart : confParts) {
118+
// If our composite config ends without a trailing newline,
119+
// append one before appending the next config part
120+
if (compositeConfig.lastIndexOf(NEWLINE) < compositeConfig.length() - 1 ) {
121+
compositeConfig.append(NEWLINE);
122+
}
123+
compositeConfig.append(confPart.getText());
124+
}
125+
this.configString = compositeConfig.toString();
117126
}
118127
}
119128
}

logstash-core/src/test/java/org/logstash/config/ir/PipelineConfigTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ static class SourceCollector {
8383

8484
void appendSource(final String protocol, final String id, final int line, final int column, final String text) throws IncompleteSourceWithMetadataException {
8585
orderedConfigParts.add(new SourceWithMetadata(protocol, id, line, column, text));
86+
87+
if (compositeSource.length() > 0 && !compositeSource.toString().endsWith("\n")) {
88+
compositeSource.append("\n");
89+
}
8690
compositeSource.append(text);
87-
compositeSource.append("\n");
8891
}
8992

9093
String compositeSource() {
@@ -103,11 +106,11 @@ public void setUp() throws IncompleteSourceWithMetadataException {
103106
pipelineIdSym = RubySymbol.newSymbol(RubyUtil.RUBY, PIPELINE_ID);
104107

105108
final SourceCollector sourceCollector = new SourceCollector();
106-
sourceCollector.appendSource("file", "/tmp/1", 0, 0, "input { generator1 }");
109+
sourceCollector.appendSource("file", "/tmp/1", 0, 0, "input { generator1 }\n");
107110
sourceCollector.appendSource("file", "/tmp/2", 0, 0, "input { generator2 }");
108-
sourceCollector.appendSource("file", "/tmp/3", 0, 0, "input { generator3 }");
111+
sourceCollector.appendSource("file", "/tmp/3", 0, 0, "input { generator3 }\n");
109112
sourceCollector.appendSource("file", "/tmp/4", 0, 0, "input { generator4 }");
110-
sourceCollector.appendSource("file", "/tmp/5", 0, 0, "input { generator5 }");
113+
sourceCollector.appendSource("file", "/tmp/5", 0, 0, "input { generator5 }\n");
111114
sourceCollector.appendSource("file", "/tmp/6", 0, 0, "input { generator6 }");
112115
sourceCollector.appendSource("string", "config_string", 0, 0, "input { generator1 }");
113116

0 commit comments

Comments
 (0)