From 556ae8f3ed0fa0519c55fecc737a872d4aed7e6b Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 16 May 2018 09:46:03 +0200 Subject: [PATCH] [CCR] Add validation checks that were left out of #30120 (#30463) --- .../xpack/ccr/FollowIndexSecurityIT.java | 9 ++ .../ccr/action/FollowExistingIndexAction.java | 91 ++++++++++--------- .../xpack/ccr/ShardChangesIT.java | 4 +- .../FollowExistingIndexActionTests.java | 66 ++++++++++++++ .../test/ccr/follow_and_unfollow.yml | 4 + 5 files changed, 130 insertions(+), 44 deletions(-) create mode 100644 x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/FollowExistingIndexActionTests.java diff --git a/x-pack/plugin/ccr/qa/multi-cluster-with-security/src/test/java/org/elasticsearch/xpack/ccr/FollowIndexSecurityIT.java b/x-pack/plugin/ccr/qa/multi-cluster-with-security/src/test/java/org/elasticsearch/xpack/ccr/FollowIndexSecurityIT.java index 85648a039c2ab..2fcc0890f2bc0 100644 --- a/x-pack/plugin/ccr/qa/multi-cluster-with-security/src/test/java/org/elasticsearch/xpack/ccr/FollowIndexSecurityIT.java +++ b/x-pack/plugin/ccr/qa/multi-cluster-with-security/src/test/java/org/elasticsearch/xpack/ccr/FollowIndexSecurityIT.java @@ -64,6 +64,11 @@ public void testFollowIndex() throws Exception { final String indexName2 = "index2"; if (runningAgainstLeaderCluster) { logger.info("Running against leader cluster"); + Settings indexSettings = Settings.builder() + .put("index.soft_deletes.enabled", true) + .build(); + createIndex(indexName1, indexSettings); + createIndex(indexName2, indexSettings); for (int i = 0; i < numDocs; i++) { logger.info("Indexing doc [{}]", i); index(indexName1, Integer.toString(i), "field", i); @@ -169,6 +174,10 @@ private static Map toMap(String response) { return XContentHelper.convertToMap(JsonXContent.jsonXContent, response, false); } + protected static void createIndex(String name, Settings settings) throws IOException { + createIndex(name, settings, ""); + } + protected static void createIndex(String name, Settings settings, String mapping) throws IOException { assertOK(adminClient().performRequest(HttpPut.METHOD_NAME, name, Collections.emptyMap(), new StringEntity("{ \"settings\": " + Strings.toString(settings) diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/FollowExistingIndexAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/FollowExistingIndexAction.java index 963f17d975882..2ebf1fc52b424 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/FollowExistingIndexAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/FollowExistingIndexAction.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.persistent.PersistentTasksCustomMetaData; import org.elasticsearch.persistent.PersistentTasksService; @@ -224,29 +225,13 @@ protected void doExecute(Request request, ActionListener listener) { */ void start(Request request, String clusterNameAlias, IndexMetaData leaderIndexMetadata, IndexMetaData followIndexMetadata, ActionListener handler) { - if (leaderIndexMetadata == null) { - handler.onFailure(new IllegalArgumentException("leader index [" + request.leaderIndex + "] does not exist")); - return; - } - - if (followIndexMetadata == null) { - handler.onFailure(new IllegalArgumentException("follow index [" + request.followIndex + "] does not exist")); - return; - } - - if (leaderIndexMetadata.getNumberOfShards() != followIndexMetadata.getNumberOfShards()) { - handler.onFailure(new IllegalArgumentException("leader index primary shards [" + - leaderIndexMetadata.getNumberOfShards() + "] does not match with the number of " + - "shards of the follow index [" + followIndexMetadata.getNumberOfShards() + "]")); - // TODO: other validation checks - } else { + validate (leaderIndexMetadata ,followIndexMetadata , request); final int numShards = followIndexMetadata.getNumberOfShards(); final AtomicInteger counter = new AtomicInteger(numShards); final AtomicReferenceArray responses = new AtomicReferenceArray<>(followIndexMetadata.getNumberOfShards()); Map filteredHeaders = threadPool.getThreadContext().getHeaders().entrySet().stream() .filter(e -> ShardFollowTask.HEADER_FILTERS.contains(e.getKey())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - for (int i = 0; i < numShards; i++) { + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));for (int i = 0; i < numShards; i++) { final int shardId = i; String taskId = followIndexMetadata.getIndexUUID() + "-" + shardId; ShardFollowTask shardFollowTask = new ShardFollowTask(clusterNameAlias, @@ -261,39 +246,59 @@ public void onResponse(PersistentTasksCustomMetaData.PersistentTask FollowExistingIndexAction.validate(null, null, request)); + assertThat(e.getMessage(), equalTo("leader index [index1] does not exist")); + } + { + IndexMetaData leaderIMD = createIMD("index1", 5); + Exception e = expectThrows(IllegalArgumentException.class, () -> FollowExistingIndexAction.validate(leaderIMD, null, request)); + assertThat(e.getMessage(), equalTo("follow index [index2] does not exist")); + } + { + IndexMetaData leaderIMD = createIMD("index1", 5); + IndexMetaData followIMD = createIMD("index2", 5); + Exception e = expectThrows(IllegalArgumentException.class, + () -> FollowExistingIndexAction.validate(leaderIMD, followIMD, request)); + assertThat(e.getMessage(), equalTo("leader index [index1] does not have soft deletes enabled")); + } + { + IndexMetaData leaderIMD = createIMD("index1", 5, new Tuple<>(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "true")); + IndexMetaData followIMD = createIMD("index2", 4); + Exception e = expectThrows(IllegalArgumentException.class, + () -> FollowExistingIndexAction.validate(leaderIMD, followIMD, request)); + assertThat(e.getMessage(), + equalTo("leader index primary shards [5] does not match with the number of shards of the follow index [4]")); + } + { + IndexMetaData leaderIMD = createIMD("index1", 5, new Tuple<>(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "true")); + IndexMetaData followIMD = createIMD("index2", 5); + FollowExistingIndexAction.validate(leaderIMD, followIMD, request); + } + } + + private static IndexMetaData createIMD(String index, int numShards, Tuple... settings) { + Settings.Builder settingsBuilder = settings(Version.CURRENT); + for (Tuple setting : settings) { + settingsBuilder.put((String) setting.v1(), (String) setting.v2()); + } + return IndexMetaData.builder(index).settings(settingsBuilder) + .numberOfShards(numShards) + .numberOfReplicas(0) + .setRoutingNumShards(numShards).build(); + } + +} diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/ccr/follow_and_unfollow.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/ccr/follow_and_unfollow.yml index 6ab9b31fd6184..2d0a361f2d492 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/ccr/follow_and_unfollow.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/ccr/follow_and_unfollow.yml @@ -4,6 +4,10 @@ indices.create: index: foo body: + settings: + index: + soft_deletes: + enabled: true mappings: doc: properties: