|
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