Skip to content

Commit 4b3de23

Browse files
Add test for system index migration using reindexing script (elastic#120644)
1 parent 40d0eb0 commit 4b3de23

File tree

6 files changed

+121
-36
lines changed

6 files changed

+121
-36
lines changed

modules/reindex/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ dependencies {
4545
clusterModules project(':modules:lang-painless')
4646
clusterModules project(':modules:parent-join')
4747
clusterModules project(":modules:rest-root")
48+
49+
internalClusterTestImplementation project(':modules:lang-painless')
50+
internalClusterTestImplementation project(':modules:lang-painless:spi')
4851
}
4952

5053
restResources {

modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/AbstractFeatureMigrationIntegTest.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public abstract class AbstractFeatureMigrationIntegTest extends ESIntegTestCase
6868
static final String INTERNAL_MANAGED_INDEX_NAME = ".int-man-old";
6969
static final int INDEX_DOC_COUNT = 100; // arbitrarily chosen
7070
static final int INTERNAL_MANAGED_FLAG_VALUE = 1;
71+
static final String FIELD_NAME = "some_field";
7172
public static final Version NEEDS_UPGRADE_VERSION = TransportGetFeatureUpgradeStatusAction.NO_UPGRADE_REQUIRED_VERSION.previousMajor();
7273
public static final IndexVersion NEEDS_UPGRADE_INDEX_VERSION = IndexVersionUtils.getPreviousMajorVersion(
7374
TransportGetFeatureUpgradeStatusAction.NO_UPGRADE_REQUIRED_INDEX_VERSION
@@ -157,7 +158,7 @@ public <T extends Plugin> T getPlugin(Class<T> type) {
157158
return pluginsService.filterPlugins(type).findFirst().get();
158159
}
159160

160-
public void createSystemIndexForDescriptor(SystemIndexDescriptor descriptor) throws InterruptedException {
161+
protected void createSystemIndexForDescriptor(SystemIndexDescriptor descriptor) {
161162
assertThat(
162163
"the strategy used below to create index names for descriptors without a primary index name only works for simple patterns",
163164
descriptor.getIndexPattern(),
@@ -191,9 +192,13 @@ public void createSystemIndexForDescriptor(SystemIndexDescriptor descriptor) thr
191192
CreateIndexResponse response = createRequest.get();
192193
Assert.assertTrue(response.isShardsAcknowledged());
193194

195+
indexDocs(indexName);
196+
}
197+
198+
protected void indexDocs(String indexName) {
194199
List<IndexRequestBuilder> docs = new ArrayList<>(INDEX_DOC_COUNT);
195200
for (int i = 0; i < INDEX_DOC_COUNT; i++) {
196-
docs.add(ESIntegTestCase.prepareIndex(indexName).setId(Integer.toString(i)).setSource("some_field", "words words"));
201+
docs.add(ESIntegTestCase.prepareIndex(indexName).setId(Integer.toString(i)).setSource(FIELD_NAME, "words words"));
197202
}
198203
indexRandom(true, docs);
199204
IndicesStatsResponse indexStats = ESIntegTestCase.indicesAdmin().prepareStats(indexName).setDocs(true).get();
@@ -218,7 +223,7 @@ static String createMapping(boolean descriptorManaged, boolean descriptorInterna
218223
builder.field("dynamic", "strict");
219224
builder.startObject("properties");
220225
{
221-
builder.startObject("some_field");
226+
builder.startObject(FIELD_NAME);
222227
builder.field("type", "keyword");
223228
builder.endObject();
224229
}
@@ -232,7 +237,7 @@ static String createMapping(boolean descriptorManaged, boolean descriptorInterna
232237
}
233238
}
234239

235-
public void assertIndexHasCorrectProperties(
240+
protected void assertIndexHasCorrectProperties(
236241
Metadata metadata,
237242
String indexName,
238243
int settingsFlagValue,

modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/FeatureMigrationIT.java

Lines changed: 104 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
2222
import org.elasticsearch.action.admin.indices.template.put.PutComponentTemplateAction;
2323
import org.elasticsearch.action.admin.indices.template.put.TransportPutComposableIndexTemplateAction;
24+
import org.elasticsearch.action.search.SearchRequestBuilder;
2425
import org.elasticsearch.action.support.ActiveShardCount;
2526
import org.elasticsearch.cluster.ClusterState;
2627
import org.elasticsearch.cluster.ClusterStateUpdateTask;
@@ -33,8 +34,11 @@
3334
import org.elasticsearch.common.Strings;
3435
import org.elasticsearch.common.compress.CompressedXContent;
3536
import org.elasticsearch.common.settings.Settings;
37+
import org.elasticsearch.index.query.QueryBuilders;
3638
import org.elasticsearch.indices.SystemIndexDescriptor;
39+
import org.elasticsearch.painless.PainlessPlugin;
3740
import org.elasticsearch.plugins.Plugin;
41+
import org.elasticsearch.plugins.SystemIndexPlugin;
3842
import org.elasticsearch.reindex.ReindexPlugin;
3943
import org.elasticsearch.upgrades.FeatureMigrationResults;
4044
import org.elasticsearch.upgrades.SingleFeatureMigrationResult;
@@ -51,6 +55,7 @@
5155
import java.util.concurrent.TimeUnit;
5256
import java.util.stream.Collectors;
5357

58+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures;
5459
import static org.hamcrest.Matchers.aMapWithSize;
5560
import static org.hamcrest.Matchers.allOf;
5661
import static org.hamcrest.Matchers.equalTo;
@@ -62,6 +67,27 @@
6267
import static org.hamcrest.Matchers.nullValue;
6368

6469
public class FeatureMigrationIT extends AbstractFeatureMigrationIntegTest {
70+
private static final String INTERNAL_MANAGED_WITH_SCRIPT_INDEX_NAME = ".int-mans-old";
71+
private static final String SCRIPTED_INDEX_FEATURE_NAME = "B-test-feature";
72+
private static final SystemIndexDescriptor INTERNAL_MANAGED_WITH_SCRIPT = SystemIndexDescriptor.builder()
73+
.setIndexPattern(".int-mans-*")
74+
.setAliasName(".internal-managed-with-script-alias")
75+
.setPrimaryIndex(INTERNAL_MANAGED_WITH_SCRIPT_INDEX_NAME)
76+
.setType(SystemIndexDescriptor.Type.INTERNAL_MANAGED)
77+
.setSettings(createSettings(NEEDS_UPGRADE_INDEX_VERSION, INTERNAL_MANAGED_FLAG_VALUE))
78+
.setMappings(createMapping(true, true))
79+
.setOrigin(ORIGIN)
80+
.setVersionMetaKey(VERSION_META_KEY)
81+
.setAllowedElasticProductOrigins(Collections.emptyList())
82+
.setMinimumNodeVersion(NEEDS_UPGRADE_VERSION)
83+
.setPriorSystemIndexDescriptors(Collections.emptyList())
84+
.setMigrationScript("""
85+
if (ctx._source.some_field != null) {
86+
ctx._source.some_field = 'migrated';
87+
}
88+
""")
89+
.build();
90+
6591
@Override
6692
protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {
6793
return Settings.builder().put(super.nodeSettings(nodeOrdinal, otherSettings)).build();
@@ -77,7 +103,9 @@ protected boolean forbidPrivateIndexSettings() {
77103
protected Collection<Class<? extends Plugin>> nodePlugins() {
78104
List<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
79105
plugins.add(TestPlugin.class);
106+
plugins.add(SecondTestPlugin.class);
80107
plugins.add(ReindexPlugin.class);
108+
plugins.add(PainlessPlugin.class);
81109
return plugins;
82110
}
83111

@@ -115,7 +143,7 @@ public void testStartMigrationAndImmediatelyCheckStatus() throws Exception {
115143
});
116144
}
117145

118-
public void testMigrateInternalManagedSystemIndex() throws Exception {
146+
public void testMigrateSystemIndex() throws Exception {
119147
createSystemIndexForDescriptor(INTERNAL_MANAGED);
120148
createSystemIndexForDescriptor(INTERNAL_UNMANAGED);
121149
createSystemIndexForDescriptor(EXTERNAL_MANAGED);
@@ -171,40 +199,15 @@ public void testMigrateInternalManagedSystemIndex() throws Exception {
171199
postUpgradeHookCalled.set(true);
172200
});
173201

174-
PostFeatureUpgradeRequest migrationRequest = new PostFeatureUpgradeRequest(TEST_REQUEST_TIMEOUT);
175-
PostFeatureUpgradeResponse migrationResponse = client().execute(PostFeatureUpgradeAction.INSTANCE, migrationRequest).get();
176-
assertThat(migrationResponse.getReason(), nullValue());
177-
assertThat(migrationResponse.getElasticsearchException(), nullValue());
178-
final Set<String> migratingFeatures = migrationResponse.getFeatures()
179-
.stream()
180-
.map(PostFeatureUpgradeResponse.Feature::getFeatureName)
181-
.collect(Collectors.toSet());
182-
assertThat(migratingFeatures, hasItem(FEATURE_NAME));
183-
184-
GetFeatureUpgradeStatusRequest getStatusRequest = new GetFeatureUpgradeStatusRequest(TEST_REQUEST_TIMEOUT);
185-
// The feature upgrade may take longer than ten seconds when tests are running
186-
// in parallel, so we give assertBusy a sixty-second timeout.
187-
assertBusy(() -> {
188-
GetFeatureUpgradeStatusResponse statusResponse = client().execute(GetFeatureUpgradeStatusAction.INSTANCE, getStatusRequest)
189-
.get();
190-
logger.info(Strings.toString(statusResponse));
191-
assertThat(statusResponse.getUpgradeStatus(), equalTo(GetFeatureUpgradeStatusResponse.UpgradeStatus.NO_MIGRATION_NEEDED));
192-
}, 60, TimeUnit.SECONDS);
202+
executeMigration(FEATURE_NAME);
193203

194204
// Waiting for shards to stabilize if indices were moved around
195205
ensureGreen();
196206

197207
assertTrue("the pre-migration hook wasn't actually called", preUpgradeHookCalled.get());
198208
assertTrue("the post-migration hook wasn't actually called", postUpgradeHookCalled.get());
199209

200-
Metadata finalMetadata = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState().metadata();
201-
// Check that the results metadata is what we expect.
202-
FeatureMigrationResults currentResults = finalMetadata.custom(FeatureMigrationResults.TYPE);
203-
assertThat(currentResults, notNullValue());
204-
assertThat(currentResults.getFeatureStatuses(), allOf(aMapWithSize(1), hasKey(FEATURE_NAME)));
205-
assertThat(currentResults.getFeatureStatuses().get(FEATURE_NAME).succeeded(), is(true));
206-
assertThat(currentResults.getFeatureStatuses().get(FEATURE_NAME).getFailedIndexName(), nullValue());
207-
assertThat(currentResults.getFeatureStatuses().get(FEATURE_NAME).getException(), nullValue());
210+
Metadata finalMetadata = assertMetadataAfterMigration(FEATURE_NAME);
208211

209212
assertIndexHasCorrectProperties(
210213
finalMetadata,
@@ -240,6 +243,18 @@ public void testMigrateInternalManagedSystemIndex() throws Exception {
240243
);
241244
}
242245

246+
private static Metadata assertMetadataAfterMigration(String featureName) {
247+
Metadata finalMetadata = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState().metadata();
248+
// Check that the results metadata is what we expect.
249+
FeatureMigrationResults currentResults = finalMetadata.custom(FeatureMigrationResults.TYPE);
250+
assertThat(currentResults, notNullValue());
251+
assertThat(currentResults.getFeatureStatuses(), allOf(aMapWithSize(1), hasKey(featureName)));
252+
assertThat(currentResults.getFeatureStatuses().get(featureName).succeeded(), is(true));
253+
assertThat(currentResults.getFeatureStatuses().get(featureName).getFailedIndexName(), nullValue());
254+
assertThat(currentResults.getFeatureStatuses().get(featureName).getException(), nullValue());
255+
return finalMetadata;
256+
}
257+
243258
public void testMigrateIndexWithWriteBlock() throws Exception {
244259
createSystemIndexForDescriptor(INTERNAL_UNMANAGED);
245260

@@ -317,6 +332,50 @@ public void onFailure(Exception e) {
317332
});
318333
}
319334

335+
private void executeMigration(String featureName) throws Exception {
336+
PostFeatureUpgradeRequest migrationRequest = new PostFeatureUpgradeRequest(TEST_REQUEST_TIMEOUT);
337+
PostFeatureUpgradeResponse migrationResponse = client().execute(PostFeatureUpgradeAction.INSTANCE, migrationRequest).get();
338+
assertThat(migrationResponse.getReason(), nullValue());
339+
assertThat(migrationResponse.getElasticsearchException(), nullValue());
340+
final Set<String> migratingFeatures = migrationResponse.getFeatures()
341+
.stream()
342+
.map(PostFeatureUpgradeResponse.Feature::getFeatureName)
343+
.collect(Collectors.toSet());
344+
assertThat(migratingFeatures, hasItem(featureName));
345+
346+
GetFeatureUpgradeStatusRequest getStatusRequest = new GetFeatureUpgradeStatusRequest(TEST_REQUEST_TIMEOUT);
347+
// The feature upgrade may take longer than ten seconds when tests are running
348+
// in parallel, so we give assertBusy a sixty-second timeout.
349+
assertBusy(() -> {
350+
GetFeatureUpgradeStatusResponse statusResponse = client().execute(GetFeatureUpgradeStatusAction.INSTANCE, getStatusRequest)
351+
.get();
352+
logger.info(Strings.toString(statusResponse));
353+
assertThat(statusResponse.getUpgradeStatus(), equalTo(GetFeatureUpgradeStatusResponse.UpgradeStatus.NO_MIGRATION_NEEDED));
354+
}, 60, TimeUnit.SECONDS);
355+
}
356+
357+
public void testMigrateUsingScript() throws Exception {
358+
createSystemIndexForDescriptor(INTERNAL_MANAGED_WITH_SCRIPT);
359+
360+
executeMigration(SCRIPTED_INDEX_FEATURE_NAME);
361+
ensureGreen();
362+
363+
Metadata metadata = assertMetadataAfterMigration(SCRIPTED_INDEX_FEATURE_NAME);
364+
String newIndexName = ".int-mans-old-reindexed-for-9";
365+
assertIndexHasCorrectProperties(
366+
metadata,
367+
newIndexName,
368+
INTERNAL_MANAGED_FLAG_VALUE,
369+
true,
370+
true,
371+
Arrays.asList(".int-mans-old", ".internal-managed-with-script-alias")
372+
);
373+
374+
SearchRequestBuilder searchRequestBuilder = prepareSearch(newIndexName).setQuery(QueryBuilders.termsQuery(FIELD_NAME, "migrated"))
375+
.setSize(0);
376+
assertHitCountAndNoFailures(searchRequestBuilder, INDEX_DOC_COUNT);
377+
}
378+
320379
private String featureUpgradeErrorResponse(GetFeatureUpgradeStatusResponse statusResp) {
321380
return statusResp.getFeatureUpgradeStatuses()
322381
.stream()
@@ -463,4 +522,21 @@ public void testMigrateWithTemplatesV2() throws Exception {
463522
assertThat(statusResp.getUpgradeStatus(), equalTo(GetFeatureUpgradeStatusResponse.UpgradeStatus.NO_MIGRATION_NEEDED));
464523
});
465524
}
525+
526+
public static class SecondTestPlugin extends Plugin implements SystemIndexPlugin {
527+
@Override
528+
public String getFeatureName() {
529+
return SCRIPTED_INDEX_FEATURE_NAME;
530+
}
531+
532+
@Override
533+
public String getFeatureDescription() {
534+
return "a plugin for testing system index migration";
535+
}
536+
537+
@Override
538+
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
539+
return Collections.singletonList(INTERNAL_MANAGED_WITH_SCRIPT);
540+
}
541+
}
466542
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
ALL-UNNAMED:
22
- outbound_network
3+
org.elasticsearch.painless:
4+
- create_class_loader

modules/reindex/src/main/plugin-metadata/plugin-security.policy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
grant {
1111
// reindex opens socket connections using the rest client
1212
permission java.net.SocketPermission "*", "connect";
13+
14+
// needed for Painless to generate runtime classes
15+
permission java.lang.RuntimePermission "createClassLoader";
1316
};
1417

1518
grant codeBase "${codebase.elasticsearch-rest-client}" {

server/src/main/java/org/elasticsearch/action/admin/cluster/migration/TransportGetFeatureUpgradeStatusAction.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.elasticsearch.indices.SystemIndices;
2525
import org.elasticsearch.injection.guice.Inject;
2626
import org.elasticsearch.persistent.PersistentTasksCustomMetadata;
27-
import org.elasticsearch.persistent.PersistentTasksService;
2827
import org.elasticsearch.tasks.Task;
2928
import org.elasticsearch.threadpool.ThreadPool;
3029
import org.elasticsearch.transport.TransportService;
@@ -56,7 +55,6 @@ public class TransportGetFeatureUpgradeStatusAction extends TransportMasterNodeA
5655
public static final IndexVersion NO_UPGRADE_REQUIRED_INDEX_VERSION = IndexVersions.V_8_0_0;
5756

5857
private final SystemIndices systemIndices;
59-
PersistentTasksService persistentTasksService;
6058

6159
@Inject
6260
public TransportGetFeatureUpgradeStatusAction(
@@ -65,7 +63,6 @@ public TransportGetFeatureUpgradeStatusAction(
6563
ActionFilters actionFilters,
6664
ClusterService clusterService,
6765
IndexNameExpressionResolver indexNameExpressionResolver,
68-
PersistentTasksService persistentTasksService,
6966
SystemIndices systemIndices
7067
) {
7168
super(
@@ -80,7 +77,6 @@ public TransportGetFeatureUpgradeStatusAction(
8077
);
8178

8279
this.systemIndices = systemIndices;
83-
this.persistentTasksService = persistentTasksService;
8480
}
8581

8682
@Override

0 commit comments

Comments
 (0)