Skip to content

Commit 78dc456

Browse files
authored
Minify Painless script before sending to OpenSearch (#6785)
Strip comment lines and blank lines from the Painless script source at initialization time. This reduces the script payload size sent to OpenSearch on every bulk request, improving network efficiency. The minification is done once in the ScriptManager constructor and the result is reused for all subsequent buildScript calls. Only full-line comments (lines starting with //) and empty lines are removed. Inline comments after code are preserved. Signed-off-by: Dinu John <86094133+dinujoh@users.noreply.github.com>
1 parent f5ece59 commit 78dc456

2 files changed

Lines changed: 87 additions & 1 deletion

File tree

data-prepper-plugins/opensearch/src/main/java/org/opensearch/dataprepper/plugins/sink/opensearch/ScriptManager.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ public class ScriptManager {
2828

2929
private final ScriptConfiguration scriptConfiguration;
3030
private final ExpressionEvaluator expressionEvaluator;
31+
private final String minifiedSource;
3132

3233
public ScriptManager(final ScriptConfiguration scriptConfiguration, final ExpressionEvaluator expressionEvaluator) {
3334
this.scriptConfiguration = scriptConfiguration;
3435
this.expressionEvaluator = expressionEvaluator;
36+
this.minifiedSource = scriptConfiguration != null ? minifyScript(scriptConfiguration.getSource()) : null;
3537
}
3638

3739
public boolean isScriptEnabled() {
@@ -61,10 +63,27 @@ public Script buildScript(final JsonNode jsonNode, final Map<String, Object> res
6163
resolvedParams.forEach((k, v) -> scriptParams.put(k, JsonData.of(v)));
6264
}
6365
final InlineScript inlineScript = new InlineScript.Builder()
64-
.source(scriptConfiguration.getSource())
66+
.source(minifiedSource)
6567
.lang(PAINLESS)
6668
.params(scriptParams)
6769
.build();
6870
return Script.of(s -> s.inline(inlineScript));
6971
}
72+
73+
static String minifyScript(final String source) {
74+
if (source == null) {
75+
return null;
76+
}
77+
final StringBuilder sb = new StringBuilder();
78+
for (final String line : source.split("\n")) {
79+
final String trimmed = line.trim();
80+
if (!trimmed.isEmpty() && !trimmed.startsWith("//")) {
81+
if (sb.length() > 0) {
82+
sb.append('\n');
83+
}
84+
sb.append(trimmed);
85+
}
86+
}
87+
return sb.toString();
88+
}
7089
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The OpenSearch Contributors require contributions made to
6+
* this file be licensed under the Apache-2.0 license or a
7+
* compatible open source license.
8+
*
9+
*/
10+
11+
package org.opensearch.dataprepper.plugins.sink.opensearch;
12+
13+
import org.junit.jupiter.api.Test;
14+
15+
import static org.hamcrest.MatcherAssert.assertThat;
16+
import static org.hamcrest.Matchers.equalTo;
17+
import static org.hamcrest.Matchers.nullValue;
18+
19+
class ScriptManagerMinifyTest {
20+
21+
@Test
22+
void minifyScript_removes_comment_lines() {
23+
final String source = "// This is a comment\nctx._source.field = params.value;\n// Another comment\nctx.op = 'none';";
24+
final String result = ScriptManager.minifyScript(source);
25+
assertThat(result, equalTo("ctx._source.field = params.value;\nctx.op = 'none';"));
26+
}
27+
28+
@Test
29+
void minifyScript_removes_blank_lines() {
30+
final String source = "ctx._source.a = 1;\n\n\nctx._source.b = 2;";
31+
final String result = ScriptManager.minifyScript(source);
32+
assertThat(result, equalTo("ctx._source.a = 1;\nctx._source.b = 2;"));
33+
}
34+
35+
@Test
36+
void minifyScript_trims_leading_whitespace() {
37+
final String source = " ctx._source.a = 1;\n ctx._source.b = 2;";
38+
final String result = ScriptManager.minifyScript(source);
39+
assertThat(result, equalTo("ctx._source.a = 1;\nctx._source.b = 2;"));
40+
}
41+
42+
@Test
43+
void minifyScript_handles_mixed_comments_blanks_and_code() {
44+
final String source = "// Header comment\n\nString table = params.table;\n// Inline explanation\nlong version = Long.parseLong(params.version);\n\n// Footer\n";
45+
final String result = ScriptManager.minifyScript(source);
46+
assertThat(result, equalTo("String table = params.table;\nlong version = Long.parseLong(params.version);"));
47+
}
48+
49+
@Test
50+
void minifyScript_returns_null_for_null_input() {
51+
assertThat(ScriptManager.minifyScript(null), nullValue());
52+
}
53+
54+
@Test
55+
void minifyScript_preserves_inline_comments_after_code() {
56+
final String source = "ctx._source.a = 1; // keep this line";
57+
final String result = ScriptManager.minifyScript(source);
58+
assertThat(result, equalTo("ctx._source.a = 1; // keep this line"));
59+
}
60+
61+
@Test
62+
void minifyScript_single_line_no_comments() {
63+
final String source = "ctx._source.counter += 1;";
64+
final String result = ScriptManager.minifyScript(source);
65+
assertThat(result, equalTo("ctx._source.counter += 1;"));
66+
}
67+
}

0 commit comments

Comments
 (0)