|
8 | 8 |
|
9 | 9 | import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
|
10 | 10 | import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
|
| 11 | +import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksAction; |
| 12 | +import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; |
| 13 | +import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; |
11 | 14 | import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
12 | 15 | import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
13 | 16 | import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
|
24 | 27 | import org.elasticsearch.common.Priority;
|
25 | 28 | import org.elasticsearch.common.Strings;
|
26 | 29 | import org.elasticsearch.common.UUIDs;
|
| 30 | +import org.elasticsearch.common.bytes.BytesReference; |
27 | 31 | import org.elasticsearch.common.network.NetworkModule;
|
28 | 32 | import org.elasticsearch.common.settings.Settings;
|
29 | 33 | import org.elasticsearch.common.unit.TimeValue;
|
| 34 | +import org.elasticsearch.common.xcontent.XContentBuilder; |
30 | 35 | import org.elasticsearch.core.internal.io.IOUtils;
|
31 | 36 | import org.elasticsearch.env.NodeEnvironment;
|
32 | 37 | import org.elasticsearch.index.Index;
|
|
35 | 40 | import org.elasticsearch.persistent.PersistentTasksCustomMetaData;
|
36 | 41 | import org.elasticsearch.plugins.Plugin;
|
37 | 42 | import org.elasticsearch.script.ScriptService;
|
| 43 | +import org.elasticsearch.tasks.TaskInfo; |
38 | 44 | import org.elasticsearch.test.ESIntegTestCase;
|
39 | 45 | import org.elasticsearch.test.ESTestCase;
|
40 | 46 | import org.elasticsearch.test.InternalTestCluster;
|
|
47 | 53 | import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata;
|
48 | 54 | import org.elasticsearch.xpack.core.ccr.ShardFollowNodeTaskStatus;
|
49 | 55 | import org.elasticsearch.xpack.core.ccr.action.FollowStatsAction;
|
| 56 | +import org.elasticsearch.xpack.core.ccr.action.PauseFollowAction; |
| 57 | +import org.elasticsearch.xpack.core.ccr.action.PutFollowAction; |
| 58 | +import org.elasticsearch.xpack.core.ccr.action.ResumeFollowAction; |
50 | 59 | import org.junit.After;
|
51 | 60 | import org.junit.AfterClass;
|
52 | 61 | import org.junit.Before;
|
|
58 | 67 | import java.util.Collection;
|
59 | 68 | import java.util.Collections;
|
60 | 69 | import java.util.Locale;
|
| 70 | +import java.util.Map; |
61 | 71 | import java.util.concurrent.CountDownLatch;
|
62 | 72 | import java.util.concurrent.TimeUnit;
|
63 | 73 | import java.util.function.Function;
|
64 | 74 |
|
| 75 | +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; |
65 | 76 | import static org.elasticsearch.discovery.DiscoveryModule.DISCOVERY_HOSTS_PROVIDER_SETTING;
|
66 | 77 | import static org.elasticsearch.discovery.zen.SettingsBasedHostsProvider.DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING;
|
67 | 78 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
68 | 79 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
| 80 | +import static org.hamcrest.Matchers.empty; |
69 | 81 | import static org.hamcrest.Matchers.equalTo;
|
70 | 82 | import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
71 | 83 |
|
@@ -284,6 +296,88 @@ protected void ensureEmptyWriteBuffers() throws Exception {
|
284 | 296 | });
|
285 | 297 | }
|
286 | 298 |
|
| 299 | + protected void pauseFollow(String... indices) throws Exception { |
| 300 | + for (String index : indices) { |
| 301 | + final PauseFollowAction.Request unfollowRequest = new PauseFollowAction.Request(index); |
| 302 | + followerClient().execute(PauseFollowAction.INSTANCE, unfollowRequest).get(); |
| 303 | + } |
| 304 | + ensureNoCcrTasks(); |
| 305 | + } |
| 306 | + |
| 307 | + protected void ensureNoCcrTasks() throws Exception { |
| 308 | + assertBusy(() -> { |
| 309 | + final ClusterState clusterState = followerClient().admin().cluster().prepareState().get().getState(); |
| 310 | + final PersistentTasksCustomMetaData tasks = clusterState.getMetaData().custom(PersistentTasksCustomMetaData.TYPE); |
| 311 | + assertThat(tasks.tasks(), empty()); |
| 312 | + |
| 313 | + ListTasksRequest listTasksRequest = new ListTasksRequest(); |
| 314 | + listTasksRequest.setDetailed(true); |
| 315 | + ListTasksResponse listTasksResponse = followerClient().admin().cluster().listTasks(listTasksRequest).get(); |
| 316 | + int numNodeTasks = 0; |
| 317 | + for (TaskInfo taskInfo : listTasksResponse.getTasks()) { |
| 318 | + if (taskInfo.getAction().startsWith(ListTasksAction.NAME) == false) { |
| 319 | + numNodeTasks++; |
| 320 | + } |
| 321 | + } |
| 322 | + assertThat(numNodeTasks, equalTo(0)); |
| 323 | + }, 30, TimeUnit.SECONDS); |
| 324 | + } |
| 325 | + |
| 326 | + protected String getIndexSettings(final int numberOfShards, final int numberOfReplicas, |
| 327 | + final Map<String, String> additionalIndexSettings) throws IOException { |
| 328 | + final String settings; |
| 329 | + try (XContentBuilder builder = jsonBuilder()) { |
| 330 | + builder.startObject(); |
| 331 | + { |
| 332 | + builder.startObject("settings"); |
| 333 | + { |
| 334 | + builder.field("index.number_of_shards", numberOfShards); |
| 335 | + builder.field("index.number_of_replicas", numberOfReplicas); |
| 336 | + for (final Map.Entry<String, String> additionalSetting : additionalIndexSettings.entrySet()) { |
| 337 | + builder.field(additionalSetting.getKey(), additionalSetting.getValue()); |
| 338 | + } |
| 339 | + } |
| 340 | + builder.endObject(); |
| 341 | + builder.startObject("mappings"); |
| 342 | + { |
| 343 | + builder.startObject("doc"); |
| 344 | + { |
| 345 | + builder.startObject("properties"); |
| 346 | + { |
| 347 | + builder.startObject("f"); |
| 348 | + { |
| 349 | + builder.field("type", "integer"); |
| 350 | + } |
| 351 | + builder.endObject(); |
| 352 | + } |
| 353 | + builder.endObject(); |
| 354 | + } |
| 355 | + builder.endObject(); |
| 356 | + } |
| 357 | + builder.endObject(); |
| 358 | + } |
| 359 | + builder.endObject(); |
| 360 | + settings = BytesReference.bytes(builder).utf8ToString(); |
| 361 | + } |
| 362 | + return settings; |
| 363 | + } |
| 364 | + |
| 365 | + public static PutFollowAction.Request putFollow(String leaderIndex, String followerIndex) { |
| 366 | + PutFollowAction.Request request = new PutFollowAction.Request(); |
| 367 | + request.setRemoteCluster("leader_cluster"); |
| 368 | + request.setLeaderIndex(leaderIndex); |
| 369 | + request.setFollowRequest(resumeFollow(followerIndex)); |
| 370 | + return request; |
| 371 | + } |
| 372 | + |
| 373 | + public static ResumeFollowAction.Request resumeFollow(String followerIndex) { |
| 374 | + ResumeFollowAction.Request request = new ResumeFollowAction.Request(); |
| 375 | + request.setFollowerIndex(followerIndex); |
| 376 | + request.setMaxRetryDelay(TimeValue.timeValueMillis(10)); |
| 377 | + request.setReadPollTimeout(TimeValue.timeValueMillis(10)); |
| 378 | + return request; |
| 379 | + } |
| 380 | + |
287 | 381 | static void removeCCRRelatedMetadataFromClusterState(ClusterService clusterService) throws Exception {
|
288 | 382 | CountDownLatch latch = new CountDownLatch(1);
|
289 | 383 | clusterService.submitStateUpdateTask("remove-ccr-related-metadata", new ClusterStateUpdateTask() {
|
|
0 commit comments