Skip to content

Commit 9aa0db9

Browse files
authored
use reflection to get past breaking change in PainlessPlugin (#137)
1 parent 7fe4fa6 commit 9aa0db9

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/main/java/co/elastic/logstash/filters/elasticintegration/EventProcessorBuilder.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,36 @@ public synchronized EventProcessor build(final PluginContext pluginContext) {
308308
}
309309

310310
private static ScriptService initScriptService(final Settings settings, final ThreadPool threadPool) {
311+
final List<Whitelist> painlessBaseWhitelist = getPainlessBaseWhiteList();
311312
final Map<ScriptContext<?>, List<Whitelist>> scriptContexts = Map.of(
312-
IngestScript.CONTEXT, PainlessPlugin.BASE_WHITELISTS,
313-
IngestConditionalScript.CONTEXT, PainlessPlugin.BASE_WHITELISTS);
313+
IngestScript.CONTEXT, painlessBaseWhitelist,
314+
IngestConditionalScript.CONTEXT, painlessBaseWhitelist);
314315

315316
Map<String, ScriptEngine> engines = new HashMap<>();
316317
engines.put(PainlessScriptEngine.NAME, new PainlessScriptEngine(settings, scriptContexts));
317318
engines.put(MustacheScriptEngine.NAME, new MustacheScriptEngine());
318319
return new ScriptService(settings, engines, ScriptModule.CORE_CONTEXTS, threadPool::absoluteTimeInMillis);
319320
}
321+
322+
/**
323+
* @implNote handles breaking changes introduced in Elasticsearch 8.14 series; once 8.14 is
324+
* released and all builds of this plugin depend on Elasticsearch 8.14+, this can
325+
* be simplified to call {@code PainlessPlugin.baseWhiteList()} directly.
326+
* @return the PainlessPlugin's default base whitelists
327+
*/
328+
@SuppressWarnings({"JavaReflectionMemberAccess", "unchecked"})
329+
static List<Whitelist> getPainlessBaseWhiteList() {
330+
Class<PainlessPlugin> cls = PainlessPlugin.class;
331+
try {
332+
try {
333+
// In 8.14+: PainlessPlugin.baseWhiteList()
334+
return (List<Whitelist>) cls.getMethod("baseWhiteList").invoke(null);
335+
} catch (NoSuchMethodException e) {
336+
// in 8.x->8.13.x: PainlessPlugin.BASE_WHITELISTS
337+
return (List<Whitelist>) cls.getField("BASE_WHITELISTS").get(null);
338+
}
339+
} catch (java.lang.reflect.InvocationTargetException | IllegalAccessException | NoSuchFieldException e) {
340+
throw new RuntimeException("Unsupported PainlessPlugin does not provide access to its base whitelists", e);
341+
}
342+
}
320343
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package co.elastic.logstash.filters.elasticintegration;
2+
3+
import org.elasticsearch.painless.spi.Whitelist;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.List;
7+
8+
import static org.hamcrest.MatcherAssert.assertThat;
9+
import static org.hamcrest.Matchers.*;
10+
11+
12+
class EventProcessorBuilderTest {
13+
14+
@Test
15+
void getPainlessBaseWhiteList() {
16+
final List<Whitelist> painlessBaseWhiteList = EventProcessorBuilder.getPainlessBaseWhiteList();
17+
assertThat(painlessBaseWhiteList, is(not(empty())));
18+
}
19+
}

0 commit comments

Comments
 (0)