|
7 | 7 | package org.elasticsearch.xpack.ccr;
|
8 | 8 |
|
9 | 9 | import com.carrotsearch.hppc.cursors.ObjectCursor;
|
| 10 | +import org.apache.lucene.util.SetOnce; |
10 | 11 | import org.elasticsearch.ElasticsearchException;
|
11 | 12 | import org.elasticsearch.ElasticsearchStatusException;
|
12 | 13 | import org.elasticsearch.ExceptionsHelper;
|
|
41 | 42 | import org.elasticsearch.action.support.WriteRequest;
|
42 | 43 | import org.elasticsearch.client.Requests;
|
43 | 44 | import org.elasticsearch.cluster.ClusterState;
|
| 45 | +import org.elasticsearch.cluster.ClusterStateUpdateTask; |
44 | 46 | import org.elasticsearch.cluster.health.ClusterIndexHealth;
|
45 | 47 | import org.elasticsearch.cluster.health.ClusterShardHealth;
|
46 | 48 | import org.elasticsearch.cluster.metadata.IndexMetaData;
|
47 | 49 | import org.elasticsearch.cluster.metadata.MappingMetaData;
|
| 50 | +import org.elasticsearch.cluster.metadata.MetaData; |
48 | 51 | import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
|
49 | 52 | import org.elasticsearch.cluster.routing.RoutingTable;
|
50 | 53 | import org.elasticsearch.cluster.service.ClusterService;
|
|
64 | 67 | import org.elasticsearch.index.seqno.RetentionLeaseActions;
|
65 | 68 | import org.elasticsearch.index.shard.ShardId;
|
66 | 69 | import org.elasticsearch.persistent.PersistentTasksCustomMetaData;
|
| 70 | +import org.elasticsearch.plugins.Plugin; |
67 | 71 | import org.elasticsearch.rest.RestStatus;
|
68 | 72 | import org.elasticsearch.snapshots.SnapshotRestoreException;
|
69 | 73 | import org.elasticsearch.tasks.TaskInfo;
|
|
84 | 88 | import org.elasticsearch.xpack.core.ccr.action.UnfollowAction;
|
85 | 89 |
|
86 | 90 | import java.io.IOException;
|
| 91 | +import java.util.Arrays; |
87 | 92 | import java.util.Collection;
|
88 | 93 | import java.util.Collections;
|
89 | 94 | import java.util.HashMap;
|
|
92 | 97 | import java.util.Map;
|
93 | 98 | import java.util.Objects;
|
94 | 99 | import java.util.Set;
|
| 100 | +import java.util.concurrent.CountDownLatch; |
95 | 101 | import java.util.concurrent.Semaphore;
|
96 | 102 | import java.util.concurrent.TimeUnit;
|
97 | 103 | import java.util.concurrent.atomic.AtomicBoolean;
|
98 | 104 | import java.util.function.BooleanSupplier;
|
99 | 105 | import java.util.function.Consumer;
|
100 | 106 | import java.util.stream.Collectors;
|
| 107 | +import java.util.stream.Stream; |
101 | 108 |
|
102 | 109 | import static java.util.Collections.singletonMap;
|
103 | 110 | import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
114 | 121 |
|
115 | 122 | public class IndexFollowingIT extends CcrIntegTestCase {
|
116 | 123 |
|
| 124 | + @Override |
| 125 | + protected Collection<Class<? extends Plugin>> nodePlugins() { |
| 126 | + return Stream.concat(super.nodePlugins().stream(), Stream.of(PrivateSettingPlugin.class)).collect(Collectors.toList()); |
| 127 | + } |
| 128 | + |
117 | 129 | public void testFollowIndex() throws Exception {
|
118 | 130 | final int numberOfPrimaryShards = randomIntBetween(1, 3);
|
119 | 131 | int numberOfReplicas = between(0, 1);
|
@@ -965,6 +977,86 @@ public void testUpdateAnalysisLeaderIndexSettings() throws Exception {
|
965 | 977 | assertThat(hasFollowIndexBeenClosedChecker.getAsBoolean(), is(true));
|
966 | 978 | }
|
967 | 979 |
|
| 980 | + public void testDoNotReplicatePrivateSettings() throws Exception { |
| 981 | + assertAcked(leaderClient().admin().indices().prepareCreate("leader").setSource( |
| 982 | + getIndexSettings(1, 0, singletonMap(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "true")), XContentType.JSON)); |
| 983 | + ensureLeaderGreen("leader"); |
| 984 | + final PutFollowAction.Request followRequest = putFollow("leader", "follower"); |
| 985 | + followerClient().execute(PutFollowAction.INSTANCE, followRequest).get(); |
| 986 | + ClusterService clusterService = getLeaderCluster().getInstance(ClusterService.class, getLeaderCluster().getMasterName()); |
| 987 | + clusterService.submitStateUpdateTask("test", new ClusterStateUpdateTask() { |
| 988 | + @Override |
| 989 | + public ClusterState execute(ClusterState currentState) { |
| 990 | + final IndexMetaData indexMetaData = currentState.metaData().index("leader"); |
| 991 | + Settings.Builder settings = Settings.builder() |
| 992 | + .put(indexMetaData.getSettings()) |
| 993 | + .put("index.max_ngram_diff", 2); |
| 994 | + if (randomBoolean()) { |
| 995 | + settings.put(PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey(), "private-value"); |
| 996 | + } |
| 997 | + if (randomBoolean()) { |
| 998 | + settings.put(PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey(), "interval-value"); |
| 999 | + } |
| 1000 | + final MetaData.Builder metadata = MetaData.builder(currentState.metaData()) |
| 1001 | + .put(IndexMetaData.builder(indexMetaData) |
| 1002 | + .settingsVersion(indexMetaData.getSettingsVersion() + 1) |
| 1003 | + .settings(settings).build(), true); |
| 1004 | + return ClusterState.builder(currentState).metaData(metadata).build(); |
| 1005 | + } |
| 1006 | + |
| 1007 | + @Override |
| 1008 | + public void onFailure(String source, Exception e) { |
| 1009 | + throw new AssertionError(e); |
| 1010 | + } |
| 1011 | + }); |
| 1012 | + assertBusy(() -> { |
| 1013 | + GetSettingsResponse resp = followerClient().admin().indices().prepareGetSettings("follower").get(); |
| 1014 | + assertThat(resp.getSetting("follower", "index.max_ngram_diff"), equalTo("2")); |
| 1015 | + assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey()), nullValue()); |
| 1016 | + assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey()), nullValue()); |
| 1017 | + }); |
| 1018 | + } |
| 1019 | + |
| 1020 | + public void testReplicatePrivateSettingsOnly() throws Exception { |
| 1021 | + assertAcked(leaderClient().admin().indices().prepareCreate("leader").setSource( |
| 1022 | + getIndexSettings(1, 0, singletonMap(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "true")), XContentType.JSON)); |
| 1023 | + ensureLeaderGreen("leader"); |
| 1024 | + followerClient().execute(PutFollowAction.INSTANCE, putFollow("leader", "follower")).get(); |
| 1025 | + final ClusterService clusterService = getLeaderCluster().getInstance(ClusterService.class, getLeaderCluster().getMasterName()); |
| 1026 | + final SetOnce<Long> settingVersionOnLeader = new SetOnce<>(); |
| 1027 | + final CountDownLatch latch = new CountDownLatch(1); |
| 1028 | + clusterService.submitStateUpdateTask("test", new ClusterStateUpdateTask() { |
| 1029 | + @Override |
| 1030 | + public ClusterState execute(ClusterState currentState) { |
| 1031 | + final IndexMetaData indexMetaData = currentState.metaData().index("leader"); |
| 1032 | + Settings.Builder settings = Settings.builder().put(indexMetaData.getSettings()); |
| 1033 | + settings.put(PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey(), "internal-value"); |
| 1034 | + settings.put(PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey(), "internal-value"); |
| 1035 | + final MetaData.Builder metadata = MetaData.builder(currentState.metaData()) |
| 1036 | + .put(IndexMetaData.builder(indexMetaData) |
| 1037 | + .settingsVersion(indexMetaData.getSettingsVersion() + 1) |
| 1038 | + .settings(settings).build(), true); |
| 1039 | + return ClusterState.builder(currentState).metaData(metadata).build(); |
| 1040 | + } |
| 1041 | + |
| 1042 | + @Override |
| 1043 | + public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { |
| 1044 | + settingVersionOnLeader.set(newState.metaData().index("leader").getSettingsVersion()); |
| 1045 | + latch.countDown(); |
| 1046 | + } |
| 1047 | + |
| 1048 | + @Override |
| 1049 | + public void onFailure(String source, Exception e) { |
| 1050 | + throw new AssertionError(e); |
| 1051 | + } |
| 1052 | + }); |
| 1053 | + latch.await(); |
| 1054 | + assertBusy(() -> assertThat(getFollowTaskSettingsVersion("follower"), equalTo(settingVersionOnLeader.get()))); |
| 1055 | + GetSettingsResponse resp = followerClient().admin().indices().prepareGetSettings("follower").get(); |
| 1056 | + assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey()), nullValue()); |
| 1057 | + assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey()), nullValue()); |
| 1058 | + } |
| 1059 | + |
968 | 1060 | public void testMustCloseIndexAndPauseToRestartWithPutFollowing() throws Exception {
|
969 | 1061 | final int numberOfPrimaryShards = randomIntBetween(1, 3);
|
970 | 1062 | final String leaderIndexSettings = getIndexSettings(numberOfPrimaryShards, between(0, 1),
|
@@ -1332,4 +1424,15 @@ private String getIndexSettingsWithNestedMapping(final int numberOfShards, final
|
1332 | 1424 | return settings;
|
1333 | 1425 | }
|
1334 | 1426 |
|
| 1427 | + public static class PrivateSettingPlugin extends Plugin { |
| 1428 | + static final Setting<String> INDEX_INTERNAL_SETTING = |
| 1429 | + Setting.simpleString("index.internal", Setting.Property.IndexScope, Setting.Property.InternalIndex); |
| 1430 | + static final Setting<String> INDEX_PRIVATE_SETTING = |
| 1431 | + Setting.simpleString("index.private", Setting.Property.IndexScope, Setting.Property.PrivateIndex); |
| 1432 | + |
| 1433 | + @Override |
| 1434 | + public List<Setting<?>> getSettings() { |
| 1435 | + return Arrays.asList(INDEX_INTERNAL_SETTING, INDEX_PRIVATE_SETTING); |
| 1436 | + } |
| 1437 | + } |
1335 | 1438 | }
|
0 commit comments