Skip to content

Commit edb577f

Browse files
authored
Scripted metric aggregations: add deprecation warning and system (#32944)
property to control legacy params (#31597) * Scripted metric aggregations: add deprecation warning and system property to control legacy params Scripted metric aggregation params._agg/_aggs are replaced by state/states context variables. By default the old params are still present, and a deprecation warning is emitted when Scripted Metric Aggregations are used. A new system property can be used to disable the legacy params. This functionality will be removed in a future revision. * Fix minor style issue and docs test failure * Disable deprecated params._agg/_aggs in tests and revise tests to use state/states instead * Add integration test covering deprecated scripted metrics aggs params._agg/_aggs access * Disable deprecated params._agg/_aggs in docs integration tests and revise stored scripts to use state/states instead * Revert unnecessary migrations doc change A relevant note should be added in the changes destined for 7.0; this PR is going to be backported to 6.x. * Replace deprecated _agg param bwc integration test with a couple of unit tests * Fix compatibility test after merge * Rename backwards compatibility system property per code review feedback * Tweak deprecation warning text per review feedback buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy server/src/test/java/org/elasticsearch/search/aggregations/metrics/scrip ted/ScriptedMetricAggregatorTests.java /Users/colings86/dev/work/git/elasticsearch/.git/worktrees/elasticsearch -6.x/CHERRY_PICK_HEAD buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts. java server/src/main/java/org/elasticsearch/search/aggregations/metrics/scrip ted/InternalScriptedMetric.java server/src/main/java/org/elasticsearch/search/aggregations/metrics/scrip ted/ScriptedMetricAggregatorFactory.java server/src/test/java/org/elasticsearch/search/aggregations/metrics/Scrip tedMetricIT.java server/src/test/java/org/elasticsearch/search/aggregations/metrics/scrip ted/InternalScriptedMetricAggStateV6CompatTests.java server/src/test/java/org/elasticsearch/search/aggregations/metrics/scrip ted/InternalScriptedMetricTests.java server/src/test/java/org/elasticsearch/search/aggregations/metrics/scrip ted/ScriptedMetricAggregatorAggStateV6CompatTests.java server/src/test/java/org/elasticsearch/search/aggregations/metrics/scrip ted/ScriptedMetricAggregatorTests.java
1 parent c1b95ba commit edb577f

File tree

11 files changed

+502
-246
lines changed

11 files changed

+502
-246
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,8 @@ class BuildPlugin implements Plugin<Project> {
798798
systemProperty 'tests.task', path
799799
systemProperty 'tests.security.manager', 'true'
800800
systemProperty 'jna.nosys', 'true'
801+
// TODO: remove this deprecation compatibility setting for 7.0
802+
systemProperty 'es.aggregations.enable_scripted_metric_agg_param', 'false'
801803
systemProperty 'es.scripting.exception_for_missing_value', 'true'
802804
systemProperty 'compiler.java', project.ext.compilerJavaVersion.getMajorVersion()
803805
if (project.ext.inFipsJvm) {

docs/build.gradle

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ integTestCluster {
4141
// TODO: remove this for 7.0, this exists to allow the doc examples in 6.x to continue using the defaults
4242
systemProperty 'es.scripting.use_java_time', 'false'
4343
systemProperty 'es.scripting.update.ctx_in_params', 'false'
44+
45+
// TODO: remove this deprecation compatibility setting for 7.0
46+
systemProperty 'es.aggregations.enable_scripted_metric_agg_param', 'false'
4447
}
4548

4649
// remove when https://github.com/elastic/elasticsearch/issues/31305 is fixed
@@ -393,25 +396,25 @@ buildRestTests.setups['stored_scripted_metric_script'] = '''
393396
- do:
394397
put_script:
395398
id: "my_init_script"
396-
body: { "script": { "lang": "painless", "source": "params._agg.transactions = []" } }
399+
body: { "script": { "lang": "painless", "source": "state.transactions = []" } }
397400
- match: { acknowledged: true }
398401
399402
- do:
400403
put_script:
401404
id: "my_map_script"
402-
body: { "script": { "lang": "painless", "source": "params._agg.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)" } }
405+
body: { "script": { "lang": "painless", "source": "state.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)" } }
403406
- match: { acknowledged: true }
404407
405408
- do:
406409
put_script:
407410
id: "my_combine_script"
408-
body: { "script": { "lang": "painless", "source": "double profit = 0;for (t in params._agg.transactions) { profit += t; } return profit" } }
411+
body: { "script": { "lang": "painless", "source": "double profit = 0;for (t in state.transactions) { profit += t; } return profit" } }
409412
- match: { acknowledged: true }
410413
411414
- do:
412415
put_script:
413416
id: "my_reduce_script"
414-
body: { "script": { "lang": "painless", "source": "double profit = 0;for (a in params._aggs) { profit += a; } return profit" } }
417+
body: { "script": { "lang": "painless", "source": "double profit = 0;for (a in states) { profit += a; } return profit" } }
415418
- match: { acknowledged: true }
416419
'''
417420

server/build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,15 @@ if (isEclipse == false || project.path == ":server-tests") {
351351
check.dependsOn integTest
352352
integTest.mustRunAfter test
353353
}
354+
// TODO: remove these compatibility tests in 7.0
355+
additionalTest('testScriptedMetricAggParamsV6Compatibility') {
356+
include '**/ScriptedMetricAggregatorAggStateV6CompatTests.class'
357+
include '**/InternalScriptedMetricAggStateV6CompatTests.class'
358+
systemProperty 'es.aggregations.enable_scripted_metric_agg_param', 'true'
359+
}
360+
361+
test {
362+
// these are tested explicitly in separate test tasks
363+
exclude '**/ScriptedMetricAggregatorAggStateV6CompatTests.class'
364+
exclude '**/InternalScriptedMetricAggStateV6CompatTests.class'
365+
}

server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.apache.lucene.index.LeafReaderContext;
2323
import org.apache.lucene.search.Scorer;
2424
import org.elasticsearch.ElasticsearchException;
25+
import org.elasticsearch.common.logging.DeprecationLogger;
26+
import org.elasticsearch.common.logging.Loggers;
2527
import org.elasticsearch.index.fielddata.ScriptDocValues;
2628
import org.elasticsearch.search.lookup.LeafSearchLookup;
2729
import org.elasticsearch.search.lookup.SearchLookup;
@@ -31,6 +33,25 @@
3133
import java.util.Map;
3234

3335
public class ScriptedMetricAggContexts {
36+
private static final DeprecationLogger DEPRECATION_LOGGER =
37+
new DeprecationLogger(Loggers.getLogger(ScriptedMetricAggContexts.class));
38+
39+
// Public for access from tests
40+
public static final String AGG_PARAM_DEPRECATION_WARNING =
41+
"params._agg/_aggs for scripted metric aggregations are deprecated, use state/states (not in params) instead. " +
42+
"Use -Des.aggregations.enable_scripted_metric_agg_param=false to disable.";
43+
44+
public static boolean deprecatedAggParamEnabled() {
45+
boolean enabled = Boolean.parseBoolean(
46+
System.getProperty("es.aggregations.enable_scripted_metric_agg_param", "true"));
47+
48+
if (enabled) {
49+
DEPRECATION_LOGGER.deprecatedAndMaybeLog("enable_scripted_metric_agg_param", AGG_PARAM_DEPRECATION_WARNING);
50+
}
51+
52+
return enabled;
53+
}
54+
3455
private abstract static class ParamsAndStateBase {
3556
private final Map<String, Object> params;
3657
private final Object state;

server/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/InternalScriptedMetric.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ public InternalAggregation doReduce(List<InternalAggregation> aggregations, Redu
9696
}
9797

9898
// Add _aggs to params map for backwards compatibility (redundant with a context variable on the ReduceScript created below).
99-
params.put("_aggs", aggregationObjects);
99+
if (ScriptedMetricAggContexts.deprecatedAggParamEnabled()) {
100+
params.put("_aggs", aggregationObjects);
101+
}
100102

101103
ScriptedMetricAggContexts.ReduceScript.Factory factory = reduceContext.scriptService().compile(
102104
firstAggregation.reduceScript, ScriptedMetricAggContexts.ReduceScript.CONTEXT);

server/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregatorFactory.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,17 @@ public Aggregator createInternal(Aggregator parent, boolean collectsFromSingleBu
8383
// Add _agg to params map for backwards compatibility (redundant with context variables on the scripts created below).
8484
// When this is removed, aggState (as passed to ScriptedMetricAggregator) can be changed to Map<String, Object>, since
8585
// it won't be possible to completely replace it with another type as is possible when it's an entry in params.
86-
if (aggParams.containsKey("_agg") == false) {
87-
aggParams.put("_agg", new HashMap<String, Object>());
86+
Object aggState = new HashMap<String, Object>();
87+
if (ScriptedMetricAggContexts.deprecatedAggParamEnabled()) {
88+
if (aggParams.containsKey("_agg") == false) {
89+
// Add _agg if it wasn't added manually
90+
aggParams.put("_agg", aggState);
91+
} else {
92+
// If it was added manually, also use it for the agg context variable to reduce the likelihood of
93+
// weird behavior due to multiple different variables.
94+
aggState = aggParams.get("_agg");
95+
}
8896
}
89-
Object aggState = aggParams.get("_agg");
9097

9198
final ScriptedMetricAggContexts.InitScript initScript = this.initScript.newInstance(
9299
mergeParams(aggParams, initScriptParams), aggState);

0 commit comments

Comments
 (0)