5
5
*/
6
6
package org .elasticsearch .xpack .ml .action ;
7
7
8
+ import org .apache .logging .log4j .LogManager ;
9
+ import org .apache .logging .log4j .Logger ;
8
10
import org .elasticsearch .Version ;
9
11
import org .elasticsearch .action .ActionListener ;
12
+ import org .elasticsearch .action .index .IndexResponse ;
10
13
import org .elasticsearch .action .support .ActionFilters ;
11
14
import org .elasticsearch .action .support .HandledTransportAction ;
12
15
import org .elasticsearch .client .Client ;
16
+ import org .elasticsearch .cluster .ClusterState ;
13
17
import org .elasticsearch .cluster .metadata .IndexNameExpressionResolver ;
14
18
import org .elasticsearch .cluster .service .ClusterService ;
15
19
import org .elasticsearch .common .Strings ;
29
33
import org .elasticsearch .xpack .core .ml .action .PutDataFrameAnalyticsAction ;
30
34
import org .elasticsearch .xpack .core .ml .dataframe .DataFrameAnalyticsConfig ;
31
35
import org .elasticsearch .xpack .core .ml .job .messages .Messages ;
36
+ import org .elasticsearch .xpack .core .ml .job .persistence .AnomalyDetectorsIndex ;
37
+ import org .elasticsearch .xpack .core .ml .job .persistence .ElasticsearchMappings ;
32
38
import org .elasticsearch .xpack .core .ml .utils .ExceptionsHelper ;
33
39
import org .elasticsearch .xpack .core .ml .utils .MlStrings ;
34
40
import org .elasticsearch .xpack .core .security .SecurityContext ;
43
49
44
50
import java .io .IOException ;
45
51
import java .time .Instant ;
52
+ import java .util .Map ;
46
53
import java .util .Objects ;
47
54
import java .util .function .Supplier ;
48
55
49
56
public class TransportPutDataFrameAnalyticsAction
50
57
extends HandledTransportAction <PutDataFrameAnalyticsAction .Request , PutDataFrameAnalyticsAction .Response > {
51
58
59
+ private static final Logger logger = LogManager .getLogger (TransportPutDataFrameAnalyticsAction .class );
60
+
52
61
private final XPackLicenseState licenseState ;
53
62
private final DataFrameAnalyticsConfigProvider configProvider ;
54
63
private final ThreadPool threadPool ;
@@ -97,6 +106,7 @@ protected void doExecute(Task task, PutDataFrameAnalyticsAction.Request request,
97
106
.setCreateTime (Instant .now ())
98
107
.setVersion (Version .CURRENT )
99
108
.build ();
109
+
100
110
if (licenseState .isAuthAllowed ()) {
101
111
final String username = securityContext .getUser ().principal ();
102
112
RoleDescriptor .IndicesPrivileges sourceIndexPrivileges = RoleDescriptor .IndicesPrivileges .builder ()
@@ -120,9 +130,12 @@ protected void doExecute(Task task, PutDataFrameAnalyticsAction.Request request,
120
130
121
131
client .execute (HasPrivilegesAction .INSTANCE , privRequest , privResponseListener );
122
132
} else {
123
- configProvider .put (memoryCappedConfig , threadPool .getThreadContext ().getHeaders (), ActionListener .wrap (
124
- indexResponse -> listener .onResponse (new PutDataFrameAnalyticsAction .Response (memoryCappedConfig )),
125
- listener ::onFailure
133
+ updateDocMappingAndPutConfig (
134
+ memoryCappedConfig ,
135
+ threadPool .getThreadContext ().getHeaders (),
136
+ ActionListener .wrap (
137
+ indexResponse -> listener .onResponse (new PutDataFrameAnalyticsAction .Response (memoryCappedConfig )),
138
+ listener ::onFailure
126
139
));
127
140
}
128
141
}
@@ -131,9 +144,12 @@ private void handlePrivsResponse(String username, DataFrameAnalyticsConfig memor
131
144
HasPrivilegesResponse response ,
132
145
ActionListener <PutDataFrameAnalyticsAction .Response > listener ) throws IOException {
133
146
if (response .isCompleteMatch ()) {
134
- configProvider .put (memoryCappedConfig , threadPool .getThreadContext ().getHeaders (), ActionListener .wrap (
135
- indexResponse -> listener .onResponse (new PutDataFrameAnalyticsAction .Response (memoryCappedConfig )),
136
- listener ::onFailure
147
+ updateDocMappingAndPutConfig (
148
+ memoryCappedConfig ,
149
+ threadPool .getThreadContext ().getHeaders (),
150
+ ActionListener .wrap (
151
+ indexResponse -> listener .onResponse (new PutDataFrameAnalyticsAction .Response (memoryCappedConfig )),
152
+ listener ::onFailure
137
153
));
138
154
} else {
139
155
XContentBuilder builder = JsonXContent .contentBuilder ();
@@ -150,6 +166,25 @@ private void handlePrivsResponse(String username, DataFrameAnalyticsConfig memor
150
166
}
151
167
}
152
168
169
+ private void updateDocMappingAndPutConfig (DataFrameAnalyticsConfig config ,
170
+ Map <String , String > headers ,
171
+ ActionListener <IndexResponse > listener ) {
172
+ ClusterState clusterState = clusterService .state ();
173
+ if (clusterState == null ) {
174
+ logger .warn ("Cannot update doc mapping because clusterState == null" );
175
+ configProvider .put (config , headers , listener );
176
+ return ;
177
+ }
178
+ ElasticsearchMappings .addDocMappingIfMissing (
179
+ AnomalyDetectorsIndex .configIndexName (),
180
+ ElasticsearchMappings ::configMapping ,
181
+ client ,
182
+ clusterState ,
183
+ ActionListener .wrap (
184
+ unused -> configProvider .put (config , headers , listener ),
185
+ listener ::onFailure ));
186
+ }
187
+
153
188
private void validateConfig (DataFrameAnalyticsConfig config ) {
154
189
if (MlStrings .isValidId (config .getId ()) == false ) {
155
190
throw ExceptionsHelper .badRequestException (Messages .getMessage (Messages .INVALID_ID , DataFrameAnalyticsConfig .ID ,
0 commit comments