org.elasticsearch.script.ScriptSettings Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch subproject :server
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.script;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class ScriptSettings {
static final String LEGACY_DEFAULT_LANG = "groovy";
/**
* The default script language to use for scripts that are stored in documents that have no script lang set explicitly.
* This setting is legacy setting and only applies for indices created on ES versions prior to version 5.0
*
* This constant will be removed in the next major release.
*/
@Deprecated
public static final String LEGACY_SCRIPT_SETTING = "script.legacy.default_lang";
private static final Map> SCRIPT_TYPE_SETTING_MAP;
static {
Map> scriptTypeSettingMap = new HashMap<>();
for (ScriptType scriptType : ScriptType.values()) {
scriptTypeSettingMap.put(scriptType, Setting.boolSetting(
ScriptModes.sourceKey(scriptType),
scriptType.isDefaultEnabled(),
Property.NodeScope));
}
SCRIPT_TYPE_SETTING_MAP = Collections.unmodifiableMap(scriptTypeSettingMap);
}
private final Map> scriptContextSettingMap;
private final List> scriptLanguageSettings;
private final Setting defaultLegacyScriptLanguageSetting;
public ScriptSettings(ScriptEngineRegistry scriptEngineRegistry, ScriptContextRegistry scriptContextRegistry) {
Map> scriptContextSettingMap = contextSettings(scriptContextRegistry);
this.scriptContextSettingMap = Collections.unmodifiableMap(scriptContextSettingMap);
List> scriptLanguageSettings = languageSettings(SCRIPT_TYPE_SETTING_MAP, scriptContextSettingMap, scriptEngineRegistry, scriptContextRegistry);
this.scriptLanguageSettings = Collections.unmodifiableList(scriptLanguageSettings);
this.defaultLegacyScriptLanguageSetting = new Setting<>(LEGACY_SCRIPT_SETTING, LEGACY_DEFAULT_LANG, setting -> {
if (!LEGACY_DEFAULT_LANG.equals(setting) && !scriptEngineRegistry.getRegisteredLanguages().containsKey(setting)) {
throw new IllegalArgumentException("unregistered default language [" + setting + "]");
}
return setting;
}, Property.NodeScope);
}
private static Map> contextSettings(ScriptContextRegistry scriptContextRegistry) {
Map> scriptContextSettingMap = new HashMap<>();
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
scriptContextSettingMap.put(scriptContext,
Setting.boolSetting(ScriptModes.operationKey(scriptContext), false, Property.NodeScope));
}
return scriptContextSettingMap;
}
private static List> languageSettings(Map> scriptTypeSettingMap,
Map> scriptContextSettingMap,
ScriptEngineRegistry scriptEngineRegistry,
ScriptContextRegistry scriptContextRegistry) {
final List> scriptModeSettings = new ArrayList<>();
for (final Class scriptEngineService : scriptEngineRegistry.getRegisteredScriptEngineServices()) {
if (scriptEngineService == NativeScriptEngineService.class) {
// native scripts are always enabled, and their settings can not be changed
continue;
}
final String language = scriptEngineRegistry.getLanguage(scriptEngineService);
for (final ScriptType scriptType : ScriptType.values()) {
// Top level, like "script.engine.groovy.inline"
final boolean defaultNonFileScriptMode = scriptEngineRegistry.getDefaultInlineScriptEnableds().get(language);
boolean defaultLangAndType = defaultNonFileScriptMode;
// Files are treated differently because they are never default-deny
if (ScriptType.FILE == scriptType) {
defaultLangAndType = ScriptType.FILE.isDefaultEnabled();
}
final boolean defaultIfNothingSet = defaultLangAndType;
Function defaultLangAndTypeFn = settings -> {
final Setting globalTypeSetting = scriptTypeSettingMap.get(scriptType);
final Setting langAndTypeSetting = Setting.boolSetting(ScriptModes.getGlobalKey(language, scriptType),
defaultIfNothingSet, Property.NodeScope);
if (langAndTypeSetting.exists(settings)) {
// fine-grained e.g. script.engine.groovy.inline
return langAndTypeSetting.get(settings).toString();
} else if (globalTypeSetting.exists(settings)) {
// global type - script.inline
return globalTypeSetting.get(settings).toString();
} else {
return Boolean.toString(defaultIfNothingSet);
}
};
// Setting for something like "script.engine.groovy.inline"
final Setting langAndTypeSetting = Setting.boolSetting(ScriptModes.getGlobalKey(language, scriptType),
defaultLangAndTypeFn, Property.NodeScope);
scriptModeSettings.add(langAndTypeSetting);
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
final String langAndTypeAndContextName = ScriptModes.getKey(language, scriptType, scriptContext);
// A function that, given a setting, will return what the default should be. Since the fine-grained script settings
// read from a bunch of different places this is implemented in this way.
Function defaultSettingFn = settings -> {
final Setting globalOpSetting = scriptContextSettingMap.get(scriptContext);
final Setting globalTypeSetting = scriptTypeSettingMap.get(scriptType);
final Setting langAndTypeAndContextSetting = Setting.boolSetting(langAndTypeAndContextName,
defaultIfNothingSet, Property.NodeScope);
// fallback logic for script mode settings
if (langAndTypeAndContextSetting.exists(settings)) {
// like: "script.engine.groovy.inline.aggs: true"
return langAndTypeAndContextSetting.get(settings).toString();
} else if (langAndTypeSetting.exists(settings)) {
// like: "script.engine.groovy.inline: true"
return langAndTypeSetting.get(settings).toString();
} else if (globalOpSetting.exists(settings)) {
// like: "script.aggs: true"
return globalOpSetting.get(settings).toString();
} else if (globalTypeSetting.exists(settings)) {
// like: "script.inline: true"
return globalTypeSetting.get(settings).toString();
} else {
// Nothing is set!
return Boolean.toString(defaultIfNothingSet);
}
};
// The actual setting for finest grained script settings
Setting setting = Setting.boolSetting(langAndTypeAndContextName, defaultSettingFn, Property.NodeScope);
scriptModeSettings.add(setting);
}
}
}
return scriptModeSettings;
}
public List> getSettings() {
List> settings = new ArrayList<>();
settings.addAll(SCRIPT_TYPE_SETTING_MAP.values());
settings.addAll(scriptContextSettingMap.values());
settings.addAll(scriptLanguageSettings);
settings.add(defaultLegacyScriptLanguageSetting);
return settings;
}
public Iterable> getScriptLanguageSettings() {
return scriptLanguageSettings;
}
public Setting getDefaultLegacyScriptLanguageSetting() {
return defaultLegacyScriptLanguageSetting;
}
public static String getLegacyDefaultLang(Settings settings) {
return settings.get(LEGACY_SCRIPT_SETTING, ScriptSettings.LEGACY_DEFAULT_LANG);
}
}