|
@@ -49,6 +49,7 @@ import org.elasticsearch.core.internal.io.IOUtils;
|
|
|
|
|
|
import java.io.Closeable;
|
|
|
import java.io.IOException;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
@@ -98,8 +99,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
public static final Setting<TimeValue> SCRIPT_CACHE_EXPIRE_SETTING =
|
|
|
Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), Property.NodeScope);
|
|
|
public static final Setting<Integer> SCRIPT_MAX_SIZE_IN_BYTES =
|
|
|
- Setting.intSetting("script.max_size_in_bytes", 65535, Property.NodeScope);
|
|
|
- // public Setting(String key, Function<Settings, String> defaultValue, Function<String, T> parser, Property... properties) {
|
|
|
+ Setting.intSetting("script.max_size_in_bytes", 65535, 0, Property.Dynamic, Property.NodeScope);
|
|
|
public static final Setting<Tuple<Integer, TimeValue>> SCRIPT_MAX_COMPILATIONS_RATE =
|
|
|
new Setting<>("script.max_compilations_rate", "75/5m", MAX_COMPILATION_RATE_FUNCTION, Property.Dynamic, Property.NodeScope);
|
|
|
|
|
@@ -123,6 +123,8 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
|
|
|
private ClusterState clusterState;
|
|
|
|
|
|
+ private int maxSizeInBytes;
|
|
|
+
|
|
|
private Tuple<Integer, TimeValue> rate;
|
|
|
private long lastInlineCompileTime;
|
|
|
private double scriptsPerTimeWindow;
|
|
@@ -221,10 +223,12 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
this.cache = cacheBuilder.removalListener(new ScriptCacheRemovalListener()).build();
|
|
|
|
|
|
this.lastInlineCompileTime = System.nanoTime();
|
|
|
+ this.setMaxSizeInBytes(SCRIPT_MAX_SIZE_IN_BYTES.get(settings));
|
|
|
this.setMaxCompilationRate(SCRIPT_MAX_COMPILATIONS_RATE.get(settings));
|
|
|
}
|
|
|
|
|
|
void registerClusterSettingsListeners(ClusterSettings clusterSettings) {
|
|
|
+ clusterSettings.addSettingsUpdateConsumer(SCRIPT_MAX_SIZE_IN_BYTES, this::setMaxSizeInBytes);
|
|
|
clusterSettings.addSettingsUpdateConsumer(SCRIPT_MAX_COMPILATIONS_RATE, this::setMaxCompilationRate);
|
|
|
}
|
|
|
|
|
@@ -241,6 +245,22 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
return scriptEngine;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Changes the maximum number of bytes a script's source is allowed to have.
|
|
|
+ * @param newMaxSizeInBytes The new maximum number of bytes.
|
|
|
+ */
|
|
|
+ void setMaxSizeInBytes(int newMaxSizeInBytes) {
|
|
|
+ for (Map.Entry<String, StoredScriptSource> source : getScriptsFromClusterState().entrySet()) {
|
|
|
+ if (source.getValue().getSource().getBytes(StandardCharsets.UTF_8).length > newMaxSizeInBytes) {
|
|
|
+ throw new IllegalArgumentException("script.max_size_in_bytes cannot be set to [" + newMaxSizeInBytes + "], " +
|
|
|
+ "stored script [" + source.getKey() + "] exceeds the new value with a size of " +
|
|
|
+ "[" + source.getValue().getSource().getBytes(StandardCharsets.UTF_8).length + "]");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ maxSizeInBytes = newMaxSizeInBytes;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* This configures the maximum script compilations per five minute window.
|
|
|
*
|
|
@@ -295,6 +315,13 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
throw new IllegalArgumentException("cannot execute scripts using [" + context.name + "] context");
|
|
|
}
|
|
|
|
|
|
+ if (type == ScriptType.INLINE) {
|
|
|
+ if (idOrCode.getBytes(StandardCharsets.UTF_8).length > maxSizeInBytes) {
|
|
|
+ throw new IllegalArgumentException("exceeded max allowed inline script size in bytes [" + maxSizeInBytes + "] " +
|
|
|
+ "with size [" + idOrCode.getBytes(StandardCharsets.UTF_8).length + "] for script [" + idOrCode + "]");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (logger.isTraceEnabled()) {
|
|
|
logger.trace("compiling lang: [{}] type: [{}] script: {}", lang, type, idOrCode);
|
|
|
}
|
|
@@ -391,6 +418,20 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
return contextsAllowed == null || contextsAllowed.isEmpty() == false;
|
|
|
}
|
|
|
|
|
|
+ Map<String, StoredScriptSource> getScriptsFromClusterState() {
|
|
|
+ if (clusterState == null) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptMetaData scriptMetadata = clusterState.metaData().custom(ScriptMetaData.TYPE);
|
|
|
+
|
|
|
+ if (scriptMetadata == null) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ return scriptMetadata.getStoredScripts();
|
|
|
+ }
|
|
|
+
|
|
|
StoredScriptSource getScriptFromClusterState(String id) {
|
|
|
ScriptMetaData scriptMetadata = clusterState.metaData().custom(ScriptMetaData.TYPE);
|
|
|
|
|
@@ -409,10 +450,8 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|
|
|
|
|
public void putStoredScript(ClusterService clusterService, PutStoredScriptRequest request,
|
|
|
ActionListener<AcknowledgedResponse> listener) {
|
|
|
- int max = SCRIPT_MAX_SIZE_IN_BYTES.get(settings);
|
|
|
-
|
|
|
- if (request.content().length() > max) {
|
|
|
- throw new IllegalArgumentException("exceeded max allowed stored script size in bytes [" + max + "] with size [" +
|
|
|
+ if (request.content().length() > maxSizeInBytes) {
|
|
|
+ throw new IllegalArgumentException("exceeded max allowed stored script size in bytes [" + maxSizeInBytes + "] with size [" +
|
|
|
request.content().length() + "] for script [" + request.id() + "]");
|
|
|
}
|
|
|
|