2525import org .elasticsearch .action .support .ActiveShardCount ;
2626import org .elasticsearch .client .Client ;
2727import org .elasticsearch .cluster .ClusterState ;
28+ import org .elasticsearch .cluster .ClusterStateUpdateTask ;
2829import org .elasticsearch .cluster .metadata .IndexMetadata ;
2930import org .elasticsearch .cluster .metadata .Metadata ;
3031import org .elasticsearch .cluster .service .ClusterService ;
3738import org .elasticsearch .reindex .ReindexPlugin ;
3839import org .elasticsearch .test .ESIntegTestCase ;
3940import org .elasticsearch .upgrades .FeatureMigrationResults ;
41+ import org .elasticsearch .upgrades .SingleFeatureMigrationResult ;
4042import org .elasticsearch .xcontent .XContentBuilder ;
4143import org .elasticsearch .xcontent .json .JsonXContent ;
4244
5052import java .util .Map ;
5153import java .util .Optional ;
5254import java .util .Set ;
55+ import java .util .concurrent .CountDownLatch ;
56+ import java .util .concurrent .TimeUnit ;
5357import java .util .concurrent .atomic .AtomicReference ;
5458import java .util .function .BiConsumer ;
5559import java .util .function .Function ;
@@ -268,6 +272,67 @@ public void testMigrateIndexWithWriteBlock() throws Exception {
268272 });
269273 }
270274
275+ public void testMigrationWillRunAfterError () throws Exception {
276+ createSystemIndexForDescriptor (INTERNAL_MANAGED );
277+
278+ TestPlugin .preMigrationHook .set ((state ) -> Collections .emptyMap ());
279+ TestPlugin .postMigrationHook .set ((state , metadata ) -> {});
280+
281+ ensureGreen ();
282+
283+ SetOnce <Exception > failure = new SetOnce <>();
284+ CountDownLatch clusterStateUpdated = new CountDownLatch (1 );
285+ internalCluster ().getCurrentMasterNodeInstance (ClusterService .class )
286+ .submitStateUpdateTask (this .getTestName (), new ClusterStateUpdateTask () {
287+ @ Override
288+ public ClusterState execute (ClusterState currentState ) throws Exception {
289+ FeatureMigrationResults newResults = new FeatureMigrationResults (
290+ Collections .singletonMap (
291+ FEATURE_NAME ,
292+ SingleFeatureMigrationResult .failure (INTERNAL_MANAGED_INDEX_NAME , new RuntimeException ("it failed :(" ))
293+ )
294+ );
295+ Metadata newMetadata = Metadata .builder (currentState .metadata ())
296+ .putCustom (FeatureMigrationResults .TYPE , newResults )
297+ .build ();
298+ return ClusterState .builder (currentState ).metadata (newMetadata ).build ();
299+ }
300+
301+ @ Override
302+ public void clusterStateProcessed (String source , ClusterState oldState , ClusterState newState ) {
303+ clusterStateUpdated .countDown ();
304+ }
305+
306+ @ Override
307+ public void onFailure (String source , Exception e ) {
308+ failure .set (e );
309+ clusterStateUpdated .countDown ();
310+ }
311+ });
312+
313+ clusterStateUpdated .await (10 , TimeUnit .SECONDS ); // Should be basically instantaneous
314+ if (failure .get () != null ) {
315+ logger .error ("cluster state update to inject migration failure state did not succeed" , failure .get ());
316+ fail ("cluster state update failed, see log for details" );
317+ }
318+
319+ PostFeatureUpgradeRequest migrationRequest = new PostFeatureUpgradeRequest ();
320+ PostFeatureUpgradeResponse migrationResponse = client ().execute (PostFeatureUpgradeAction .INSTANCE , migrationRequest ).get ();
321+ // Make sure we actually started the migration
322+ assertTrue (
323+ "could not find [" + FEATURE_NAME + "] in response: " + Strings .toString (migrationResponse ),
324+ migrationResponse .getFeatures ().stream ().anyMatch (feature -> feature .getFeatureName ().equals (FEATURE_NAME ))
325+ );
326+
327+ // Now wait for the migration to finish (otherwise the test infra explodes)
328+ assertBusy (() -> {
329+ GetFeatureUpgradeStatusRequest getStatusRequest = new GetFeatureUpgradeStatusRequest ();
330+ GetFeatureUpgradeStatusResponse statusResp = client ().execute (GetFeatureUpgradeStatusAction .INSTANCE , getStatusRequest ).get ();
331+ logger .info (Strings .toString (statusResp ));
332+ assertThat (statusResp .getUpgradeStatus (), equalTo (GetFeatureUpgradeStatusResponse .UpgradeStatus .NO_MIGRATION_NEEDED ));
333+ });
334+ }
335+
271336 public void assertIndexHasCorrectProperties (
272337 Metadata metadata ,
273338 String indexName ,
@@ -345,6 +410,7 @@ public void createSystemIndexForDescriptor(SystemIndexDescriptor descriptor) thr
345410 static final String FEATURE_NAME = "A-test-feature" ; // Sorts alphabetically before the feature from MultiFeatureMigrationIT
346411 static final String ORIGIN = FeatureMigrationIT .class .getSimpleName ();
347412 static final String FlAG_SETTING_KEY = IndexMetadata .INDEX_PRIORITY_SETTING .getKey ();
413+ static final String INTERNAL_MANAGED_INDEX_NAME = ".int-man-old" ;
348414 static final int INDEX_DOC_COUNT = 100 ; // arbitrarily chosen
349415 public static final Version NEEDS_UPGRADE_VERSION = Version .V_7_0_0 ;
350416
@@ -355,7 +421,7 @@ public void createSystemIndexForDescriptor(SystemIndexDescriptor descriptor) thr
355421 static final SystemIndexDescriptor INTERNAL_MANAGED = SystemIndexDescriptor .builder ()
356422 .setIndexPattern (".int-man-*" )
357423 .setAliasName (".internal-managed-alias" )
358- .setPrimaryIndex (".int-man-old" )
424+ .setPrimaryIndex (INTERNAL_MANAGED_INDEX_NAME )
359425 .setType (SystemIndexDescriptor .Type .INTERNAL_MANAGED )
360426 .setSettings (createSimpleSettings (NEEDS_UPGRADE_VERSION , INTERNAL_MANAGED_FLAG_VALUE ))
361427 .setMappings (createSimpleMapping (true , true ))
0 commit comments