Skip to content

Commit eb43cde

Browse files
committed
migrate ScriptServiceBridge to interface pattern
1 parent 2846dc9 commit eb43cde

File tree

1 file changed

+89
-74
lines changed

1 file changed

+89
-74
lines changed

libs/logstash-bridge/src/main/java/org/elasticsearch/logstashbridge/script/ScriptServiceBridge.java

Lines changed: 89 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -43,96 +43,111 @@
4343
/**
4444
* An external bridge for {@link ScriptService}
4545
*/
46-
public class ScriptServiceBridge extends StableBridgeAPI.ProxyInternal<ScriptService> implements Closeable {
47-
public ScriptServiceBridge fromInternal(final ScriptService delegate) {
48-
return new ScriptServiceBridge(delegate);
49-
}
46+
public interface ScriptServiceBridge extends StableBridgeAPI<ScriptService>, Closeable {
5047

51-
public ScriptServiceBridge(final SettingsBridge settingsBridge, final LongSupplier timeProvider) throws IOException {
52-
super(getScriptService(settingsBridge.toInternal(), timeProvider));
48+
static ScriptServiceBridge fromInternal(final ScriptService delegate) {
49+
return new ScriptServiceBridge.ProxyInternal(delegate);
5350
}
5451

55-
public ScriptServiceBridge(ScriptService delegate) {
56-
super(delegate);
52+
static ScriptServiceBridge create(final SettingsBridge bridgedSettings, final LongSupplier timeProvider) throws IOException {
53+
final ScriptService internal = ProxyInternal.getScriptService(bridgedSettings.toInternal(), timeProvider);
54+
return fromInternal(internal);
5755
}
5856

59-
private static ScriptService getScriptService(final Settings settings, final LongSupplier timeProvider) throws IOException {
60-
final List<Whitelist> painlessBaseWhitelist = getPainlessBaseWhiteList();
61-
final Map<ScriptContext<?>, List<Whitelist>> scriptContexts = Map.of(
62-
IngestScript.CONTEXT,
63-
painlessBaseWhitelist,
64-
IngestConditionalScript.CONTEXT,
65-
painlessBaseWhitelist
66-
);
67-
final Map<String, ScriptEngine> scriptEngines = Map.of(
68-
PainlessScriptEngine.NAME,
69-
getPainlessScriptEngine(settings),
70-
MustacheScriptEngine.NAME,
71-
new MustacheScriptEngine(settings)
72-
);
73-
74-
return new ScriptService(settings, scriptEngines, ScriptModule.CORE_CONTEXTS, timeProvider, ProjectIdResolverBridge.INSTANCE);
75-
}
57+
class ProxyInternal extends StableBridgeAPI.ProxyInternal<ScriptService> implements ScriptServiceBridge {
7658

77-
private static List<Whitelist> getPainlessBaseWhiteList() {
78-
return PainlessPlugin.baseWhiteList();
79-
}
59+
public ProxyInternal(final SettingsBridge settingsBridge, final LongSupplier timeProvider) throws IOException {
60+
super(getScriptService(settingsBridge.toInternal(), timeProvider));
61+
}
8062

81-
/**
82-
* @param settings the Elasticsearch settings object
83-
* @return a {@link ScriptEngine} for painless scripts for use in {@link IngestScript} and
84-
* {@link IngestConditionalScript} contexts, including all available {@link PainlessExtension}s.
85-
* @throws IOException when the underlying script engine cannot be created
86-
*/
87-
private static ScriptEngine getPainlessScriptEngine(final Settings settings) throws IOException {
88-
try (PainlessPlugin painlessPlugin = new PainlessPlugin()) {
89-
painlessPlugin.loadExtensions(new ExtensiblePlugin.ExtensionLoader() {
90-
@Override
91-
@SuppressWarnings("unchecked")
92-
public <T> List<T> loadExtensions(Class<T> extensionPointType) {
93-
if (extensionPointType.isAssignableFrom(PainlessExtension.class)) {
94-
final List<PainlessExtension> extensions = new ArrayList<>();
95-
96-
extensions.add(new ConstantKeywordPainlessExtension()); // module: constant-keyword
97-
extensions.add(new ProcessorsWhitelistExtension()); // module: ingest-common
98-
extensions.add(new SpatialPainlessExtension()); // module: spatial
99-
extensions.add(new WildcardPainlessExtension()); // module: wildcard
100-
101-
return (List<T>) extensions;
102-
} else {
103-
return List.of();
104-
}
105-
}
106-
});
63+
public ProxyInternal(ScriptService delegate) {
64+
super(delegate);
65+
}
10766

108-
return painlessPlugin.getScriptEngine(settings, Set.of(IngestScript.CONTEXT, IngestConditionalScript.CONTEXT));
67+
private static ScriptService getScriptService(final Settings settings, final LongSupplier timeProvider) throws IOException {
68+
final List<Whitelist> painlessBaseWhitelist = getPainlessBaseWhiteList();
69+
final Map<ScriptContext<?>, List<Whitelist>> scriptContexts = Map.of(
70+
IngestScript.CONTEXT,
71+
painlessBaseWhitelist,
72+
IngestConditionalScript.CONTEXT,
73+
painlessBaseWhitelist
74+
);
75+
final Map<String, ScriptEngine> scriptEngines = Map.of(
76+
PainlessScriptEngine.NAME,
77+
getPainlessScriptEngine(settings),
78+
MustacheScriptEngine.NAME,
79+
new MustacheScriptEngine(settings)
80+
);
81+
82+
return new ScriptService(
83+
settings,
84+
scriptEngines,
85+
ScriptModule.CORE_CONTEXTS,
86+
timeProvider,
87+
LockdownOnlyDefaultProjectIdResolver.INSTANCE
88+
);
10989
}
110-
}
11190

112-
@Override
113-
public void close() throws IOException {
114-
this.internalDelegate.close();
115-
}
91+
private static List<Whitelist> getPainlessBaseWhiteList() {
92+
return PainlessPlugin.baseWhiteList();
93+
}
11694

117-
@FixForMultiProject
118-
// Logstash resolves and runs ingest pipelines based on the datastream.
119-
// How should ProjectIdResolverBridge behave in this case?
120-
// In other words, it looks we need to find a way to figure out which ingest pipeline belongs to which project.
121-
static class ProjectIdResolverBridge implements ProjectResolver {
95+
/**
96+
* @param settings the Elasticsearch settings object
97+
* @return a {@link ScriptEngine} for painless scripts for use in {@link IngestScript} and
98+
* {@link IngestConditionalScript} contexts, including all available {@link PainlessExtension}s.
99+
* @throws IOException when the underlying script engine cannot be created
100+
*/
101+
private static ScriptEngine getPainlessScriptEngine(final Settings settings) throws IOException {
102+
try (PainlessPlugin painlessPlugin = new PainlessPlugin()) {
103+
painlessPlugin.loadExtensions(new ExtensiblePlugin.ExtensionLoader() {
104+
@Override
105+
@SuppressWarnings("unchecked")
106+
public <T> List<T> loadExtensions(Class<T> extensionPointType) {
107+
if (extensionPointType.isAssignableFrom(PainlessExtension.class)) {
108+
final List<PainlessExtension> extensions = new ArrayList<>();
109+
110+
extensions.add(new ConstantKeywordPainlessExtension()); // module: constant-keyword
111+
extensions.add(new ProcessorsWhitelistExtension()); // module: ingest-common
112+
extensions.add(new SpatialPainlessExtension()); // module: spatial
113+
extensions.add(new WildcardPainlessExtension()); // module: wildcard
114+
115+
return (List<T>) extensions;
116+
} else {
117+
return List.of();
118+
}
119+
}
120+
});
122121

123-
public static final ProjectIdResolverBridge INSTANCE = new ProjectIdResolverBridge();
122+
return painlessPlugin.getScriptEngine(settings, Set.of(IngestScript.CONTEXT, IngestConditionalScript.CONTEXT));
123+
}
124+
}
124125

125126
@Override
126-
public ProjectId getProjectId() {
127-
return ProjectId.DEFAULT;
127+
public void close() throws IOException {
128+
this.internalDelegate.close();
128129
}
129130

130-
@Override
131-
public <E extends Exception> void executeOnProject(ProjectId projectId, CheckedRunnable<E> body) throws E {
132-
if (projectId.equals(ProjectId.DEFAULT)) {
133-
body.run();
134-
} else {
135-
throw new IllegalArgumentException("Cannot execute on a project other than [" + ProjectId.DEFAULT + "]");
131+
@FixForMultiProject
132+
// Logstash resolves and runs ingest pipelines based on the datastream.
133+
// How should LockdownOnlyDefaultProjectIdResolver behave in this case?
134+
// In other words, it looks we need to find a way to figure out which ingest pipeline belongs to which project.
135+
static class LockdownOnlyDefaultProjectIdResolver implements ProjectResolver {
136+
137+
public static final LockdownOnlyDefaultProjectIdResolver INSTANCE = new LockdownOnlyDefaultProjectIdResolver();
138+
139+
@Override
140+
public ProjectId getProjectId() {
141+
return ProjectId.DEFAULT;
142+
}
143+
144+
@Override
145+
public <E extends Exception> void executeOnProject(ProjectId projectId, CheckedRunnable<E> body) throws E {
146+
if (projectId.equals(ProjectId.DEFAULT)) {
147+
body.run();
148+
} else {
149+
throw new IllegalArgumentException("Cannot execute on a project other than [" + ProjectId.DEFAULT + "]");
150+
}
136151
}
137152
}
138153
}

0 commit comments

Comments
 (0)