|
27 | 27 | import org.elasticsearch.license.License;
|
28 | 28 | import org.elasticsearch.license.LicenseUtils;
|
29 | 29 | import org.elasticsearch.license.XPackLicenseState;
|
| 30 | +import org.elasticsearch.search.builder.SearchSourceBuilder; |
30 | 31 | import org.elasticsearch.tasks.Task;
|
31 | 32 | import org.elasticsearch.threadpool.ThreadPool;
|
32 | 33 | import org.elasticsearch.transport.TransportService;
|
|
39 | 40 | import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsConfig;
|
40 | 41 | import org.elasticsearch.xpack.core.ml.job.messages.Messages;
|
41 | 42 | import org.elasticsearch.xpack.core.ml.job.persistence.ElasticsearchMappings;
|
| 43 | +import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper; |
42 | 44 | import org.elasticsearch.xpack.core.security.SecurityContext;
|
43 | 45 | import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesAction;
|
44 | 46 | import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest;
|
@@ -115,6 +117,21 @@ protected void masterOperation(PutDataFrameAnalyticsAction.Request request, Clus
|
115 | 117 |
|
116 | 118 | final DataFrameAnalyticsConfig config = request.getConfig();
|
117 | 119 |
|
| 120 | + // Check if runtime mappings are used but the cluster contains nodes on a version |
| 121 | + // before runtime fields were introduced and reject such configs. |
| 122 | + if (config.getSource().getRuntimeMappings().isEmpty() == false && state.nodes().getMinNodeVersion().before(Version.V_7_11_0)) { |
| 123 | + listener.onFailure(ExceptionsHelper.badRequestException( |
| 124 | + "at least one cluster node is on a version [{}] that does not support [{}]; " + |
| 125 | + "all nodes should be at least on version [{}] in order to create data frame analytics with [{}]", |
| 126 | + state.nodes().getMinNodeVersion(), |
| 127 | + SearchSourceBuilder.RUNTIME_MAPPINGS_FIELD.getPreferredName(), |
| 128 | + Version.V_7_11_0, |
| 129 | + SearchSourceBuilder.RUNTIME_MAPPINGS_FIELD.getPreferredName() |
| 130 | + ) |
| 131 | + ); |
| 132 | + return; |
| 133 | + } |
| 134 | + |
118 | 135 | ActionListener<Boolean> sourceDestValidationListener = ActionListener.wrap(
|
119 | 136 | aBoolean -> putValidatedConfig(config, listener),
|
120 | 137 | listener::onFailure
|
|
0 commit comments