2121import org .elasticsearch .common .inject .Inject ;
2222import org .elasticsearch .common .unit .TimeValue ;
2323import org .elasticsearch .discovery .MasterNotDiscoveredException ;
24+ import org .elasticsearch .persistent .PersistentTasksCustomMetaData ;
2425import org .elasticsearch .persistent .PersistentTasksService ;
2526import org .elasticsearch .rest .RestStatus ;
2627import org .elasticsearch .tasks .Task ;
2728import org .elasticsearch .threadpool .ThreadPool ;
2829import org .elasticsearch .transport .TransportService ;
2930import org .elasticsearch .xpack .core .action .util .PageParams ;
31+ import org .elasticsearch .xpack .core .dataframe .DataFrameMessages ;
3032import org .elasticsearch .xpack .core .dataframe .action .StopDataFrameTransformAction ;
33+ import org .elasticsearch .xpack .core .dataframe .transforms .DataFrameTransformState ;
3134import org .elasticsearch .xpack .core .dataframe .transforms .DataFrameTransformTaskState ;
3235import org .elasticsearch .xpack .dataframe .persistence .DataFrameInternalIndex ;
3336import org .elasticsearch .xpack .dataframe .persistence .DataFrameTransformsConfigManager ;
3437import org .elasticsearch .xpack .dataframe .transforms .DataFrameTransformTask ;
3538
39+ import java .util .ArrayList ;
3640import java .util .Collection ;
3741import java .util .HashSet ;
3842import java .util .List ;
3943import java .util .Set ;
4044
45+ import static org .elasticsearch .xpack .core .dataframe .DataFrameMessages .DATA_FRAME_CANNOT_STOP_FAILED_TRANSFORM ;
46+
4147public class TransportStopDataFrameTransformAction extends
4248 TransportTasksAction <DataFrameTransformTask , StopDataFrameTransformAction .Request ,
4349 StopDataFrameTransformAction .Response , StopDataFrameTransformAction .Response > {
@@ -63,6 +69,32 @@ public TransportStopDataFrameTransformAction(TransportService transportService,
6369 this .client = client ;
6470 }
6571
72+ static void validateTaskState (ClusterState state , List <String > transformIds , boolean isForce ) {
73+ PersistentTasksCustomMetaData tasks = state .metaData ().custom (PersistentTasksCustomMetaData .TYPE );
74+ if (isForce == false && tasks != null ) {
75+ List <String > failedTasks = new ArrayList <>();
76+ List <String > failedReasons = new ArrayList <>();
77+ for (String transformId : transformIds ) {
78+ PersistentTasksCustomMetaData .PersistentTask <?> dfTask = tasks .getTask (transformId );
79+ if (dfTask != null
80+ && dfTask .getState () instanceof DataFrameTransformState
81+ && ((DataFrameTransformState ) dfTask .getState ()).getTaskState () == DataFrameTransformTaskState .FAILED ) {
82+ failedTasks .add (transformId );
83+ failedReasons .add (((DataFrameTransformState ) dfTask .getState ()).getReason ());
84+ }
85+ }
86+ if (failedTasks .isEmpty () == false ) {
87+ String msg = failedTasks .size () == 1 ?
88+ DataFrameMessages .getMessage (DATA_FRAME_CANNOT_STOP_FAILED_TRANSFORM ,
89+ failedTasks .get (0 ),
90+ failedReasons .get (0 )) :
91+ "Unable to stop data frame transforms. The following transforms are in a failed state " +
92+ failedTasks + " with reasons " + failedReasons + ". Use force stop to stop the data frame transforms." ;
93+ throw new ElasticsearchStatusException (msg , RestStatus .CONFLICT );
94+ }
95+ }
96+ }
97+
6698 @ Override
6799 protected void doExecute (Task task , StopDataFrameTransformAction .Request request ,
68100 ActionListener <StopDataFrameTransformAction .Response > listener ) {
@@ -88,8 +120,9 @@ protected void doExecute(Task task, StopDataFrameTransformAction.Request request
88120 new PageParams (0 , 10_000 ),
89121 request .isAllowNoMatch (),
90122 ActionListener .wrap (hitsAndIds -> {
123+ validateTaskState (state , hitsAndIds .v2 (), request .isForce ());
91124 request .setExpandedIds (new HashSet <>(hitsAndIds .v2 ()));
92- request .setNodes (DataFrameNodes .dataFrameTaskNodes (hitsAndIds .v2 (), clusterService . state () ));
125+ request .setNodes (DataFrameNodes .dataFrameTaskNodes (hitsAndIds .v2 (), state ));
93126 super .doExecute (task , request , finalListener );
94127 },
95128 listener ::onFailure
@@ -108,11 +141,14 @@ protected void taskOperation(StopDataFrameTransformAction.Request request, DataF
108141 }
109142
110143 if (ids .contains (transformTask .getTransformId ())) {
144+ // This should not occur as we validate that none of the tasks are in a failed state earlier
145+ // Keep this check in here for insurance.
111146 if (transformTask .getState ().getTaskState () == DataFrameTransformTaskState .FAILED && request .isForce () == false ) {
112147 listener .onFailure (
113- new ElasticsearchStatusException ("Unable to stop data frame transform [" + request .getId ()
114- + "] as it is in a failed state with reason: [" + transformTask .getState ().getReason () +
115- "]. Use force stop to stop the data frame transform." ,
148+ new ElasticsearchStatusException (
149+ DataFrameMessages .getMessage (DATA_FRAME_CANNOT_STOP_FAILED_TRANSFORM ,
150+ request .getId (),
151+ transformTask .getState ().getReason ()),
116152 RestStatus .CONFLICT ));
117153 return ;
118154 }
0 commit comments