1
0
Эх сурвалжийг харах

HLRC: add support for the searchable_snapshot ILM action (#62323)

Andrei Dan 5 жил өмнө
parent
commit
681eb58718

+ 3 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/ilm/IndexLifecycleNamedXContentProvider.java

@@ -60,6 +60,9 @@ public class IndexLifecycleNamedXContentProvider implements NamedXContentProvide
             new NamedXContentRegistry.Entry(LifecycleAction.class,
                 new ParseField(MigrateAction.NAME),
                 MigrateAction::parse),
+            new NamedXContentRegistry.Entry(LifecycleAction.class,
+                new ParseField(SearchableSnapshotAction.NAME),
+                SearchableSnapshotAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class,
                 new ParseField(UnfollowAction.NAME),
                 UnfollowAction::parse)

+ 1 - 1
client/rest-high-level/src/main/java/org/elasticsearch/client/ilm/LifecyclePolicy.java

@@ -61,7 +61,7 @@ public class LifecyclePolicy implements ToXContentObject {
         ALLOWED_ACTIONS.put("warm", Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, MigrateAction.NAME, AllocateAction.NAME,
             ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME));
         ALLOWED_ACTIONS.put("cold", Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, MigrateAction.NAME, AllocateAction.NAME,
-            FreezeAction.NAME));
+            FreezeAction.NAME, SearchableSnapshotAction.NAME));
         ALLOWED_ACTIONS.put("delete", Sets.newHashSet(DeleteAction.NAME));
     }
 

+ 100 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/ilm/SearchableSnapshotAction.java

@@ -0,0 +1,100 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ilm;
+
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * A {@link LifecycleAction} that will convert the index into a searchable snapshot.
+ */
+public class SearchableSnapshotAction implements LifecycleAction, ToXContentObject {
+    public static final String NAME = "searchable_snapshot";
+
+    public static final ParseField SNAPSHOT_REPOSITORY = new ParseField("snapshot_repository");
+    public static final ParseField FORCE_MERGE_INDEX = new ParseField("force_merge_index");
+
+
+    private static final ConstructingObjectParser<SearchableSnapshotAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
+        true, a -> new SearchableSnapshotAction((String) a[0], a[1] == null || (boolean) a[1]));
+
+    static {
+        PARSER.declareString(ConstructingObjectParser.constructorArg(), SNAPSHOT_REPOSITORY);
+        PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), FORCE_MERGE_INDEX);
+    }
+
+    public static SearchableSnapshotAction parse(XContentParser parser) {
+        return PARSER.apply(parser, null);
+    }
+
+    private final String snapshotRepository;
+    private final boolean forceMergeIndex;
+
+    public SearchableSnapshotAction(String snapshotRepository, boolean forceMergeIndex) {
+        if (Strings.hasText(snapshotRepository) == false) {
+            throw new IllegalArgumentException("the snapshot repository must be specified");
+        }
+        this.snapshotRepository = snapshotRepository;
+        this.forceMergeIndex = forceMergeIndex;
+    }
+
+    public SearchableSnapshotAction(String snapshotRepository) {
+        this(snapshotRepository, true);
+    }
+
+    boolean isForceMergeIndex() {
+        return forceMergeIndex;
+    }
+
+    @Override
+    public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
+        builder.startObject();
+        builder.field(SNAPSHOT_REPOSITORY.getPreferredName(), snapshotRepository);
+        builder.field(FORCE_MERGE_INDEX.getPreferredName(), forceMergeIndex);
+        builder.endObject();
+        return builder;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        SearchableSnapshotAction that = (SearchableSnapshotAction) o;
+        return forceMergeIndex == that.forceMergeIndex &&
+            snapshotRepository.equals(that.snapshotRepository);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(snapshotRepository, forceMergeIndex);
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+}

+ 2 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java

@@ -45,6 +45,7 @@ import org.elasticsearch.client.ilm.RemoveIndexLifecyclePolicyRequest;
 import org.elasticsearch.client.ilm.RemoveIndexLifecyclePolicyResponse;
 import org.elasticsearch.client.ilm.RetryLifecyclePolicyRequest;
 import org.elasticsearch.client.ilm.RolloverAction;
+import org.elasticsearch.client.ilm.SearchableSnapshotAction;
 import org.elasticsearch.client.ilm.ShrinkAction;
 import org.elasticsearch.client.ilm.StartILMRequest;
 import org.elasticsearch.client.ilm.StopILMRequest;
@@ -160,6 +161,7 @@ public class IndexLifecycleIT extends ESRestHighLevelClientTestCase {
         Map<String, LifecycleAction> coldActions = new HashMap<>();
         coldActions.put(UnfollowAction.NAME, new UnfollowAction());
         coldActions.put(AllocateAction.NAME, new AllocateAction(0, null, null, null));
+        coldActions.put(SearchableSnapshotAction.NAME, new SearchableSnapshotAction("repo"));
         lifecyclePhases.put("cold", new Phase("cold", TimeValue.timeValueSeconds(2000), coldActions));
 
         Map<String, LifecycleAction> deleteActions = Collections.singletonMap(DeleteAction.NAME, new DeleteAction());

+ 4 - 2
client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java

@@ -52,6 +52,7 @@ import org.elasticsearch.client.ilm.FreezeAction;
 import org.elasticsearch.client.ilm.LifecycleAction;
 import org.elasticsearch.client.ilm.ReadOnlyAction;
 import org.elasticsearch.client.ilm.RolloverAction;
+import org.elasticsearch.client.ilm.SearchableSnapshotAction;
 import org.elasticsearch.client.ilm.SetPriorityAction;
 import org.elasticsearch.client.ilm.ShrinkAction;
 import org.elasticsearch.client.ilm.UnfollowAction;
@@ -705,7 +706,7 @@ public class RestHighLevelClientTests extends ESTestCase {
 
     public void testProvidedNamedXContents() {
         List<NamedXContentRegistry.Entry> namedXContents = RestHighLevelClient.getProvidedNamedXContents();
-        assertEquals(71, namedXContents.size());
+        assertEquals(72, namedXContents.size());
         Map<Class<?>, Integer> categories = new HashMap<>();
         List<String> names = new ArrayList<>();
         for (NamedXContentRegistry.Entry namedXContent : namedXContents) {
@@ -731,7 +732,7 @@ public class RestHighLevelClientTests extends ESTestCase {
         assertTrue(names.contains(MeanReciprocalRank.NAME));
         assertTrue(names.contains(DiscountedCumulativeGain.NAME));
         assertTrue(names.contains(ExpectedReciprocalRank.NAME));
-        assertEquals(Integer.valueOf(10), categories.get(LifecycleAction.class));
+        assertEquals(Integer.valueOf(11), categories.get(LifecycleAction.class));
         assertTrue(names.contains(UnfollowAction.NAME));
         assertTrue(names.contains(AllocateAction.NAME));
         assertTrue(names.contains(DeleteAction.NAME));
@@ -741,6 +742,7 @@ public class RestHighLevelClientTests extends ESTestCase {
         assertTrue(names.contains(ShrinkAction.NAME));
         assertTrue(names.contains(FreezeAction.NAME));
         assertTrue(names.contains(SetPriorityAction.NAME));
+        assertTrue(names.contains(SearchableSnapshotAction.NAME));
         assertEquals(Integer.valueOf(3), categories.get(DataFrameAnalysis.class));
         assertTrue(names.contains(org.elasticsearch.client.ml.dataframe.OutlierDetection.NAME.getPreferredName()));
         assertTrue(names.contains(org.elasticsearch.client.ml.dataframe.Regression.NAME.getPreferredName()));

+ 2 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/ilm/GetLifecyclePolicyResponseTests.java

@@ -86,6 +86,8 @@ public class GetLifecyclePolicyResponseTests extends AbstractXContentTestCase<Ge
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse),
+            new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SearchableSnapshotAction.NAME),
+                SearchableSnapshotAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse)
         ));
         return new NamedXContentRegistry(entries);

+ 2 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/ilm/LifecyclePolicyMetadataTests.java

@@ -80,6 +80,8 @@ public class LifecyclePolicyMetadataTests extends AbstractXContentTestCase<Lifec
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse),
+            new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SearchableSnapshotAction.NAME),
+                SearchableSnapshotAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse)
         ));
         return new NamedXContentRegistry(entries);

+ 7 - 1
client/rest-high-level/src/test/java/org/elasticsearch/client/ilm/LifecyclePolicyTests.java

@@ -44,7 +44,7 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
     private static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, AllocateAction.NAME,
         ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME);
     private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, AllocateAction.NAME,
-        FreezeAction.NAME);
+        FreezeAction.NAME, SearchableSnapshotAction.NAME);
     private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME);
 
     private String lifecycleName;
@@ -77,6 +77,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse),
+            new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SearchableSnapshotAction.NAME),
+                SearchableSnapshotAction::parse),
             new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse)
         ));
         return new NamedXContentRegistry(entries);
@@ -224,6 +226,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
                     return SetPriorityActionTests.randomInstance();
                 case UnfollowAction.NAME:
                     return new UnfollowAction();
+                case SearchableSnapshotAction.NAME:
+                    return SearchableSnapshotActionTests.randomInstance();
                 default:
                     throw new IllegalArgumentException("invalid action [" + action + "]");
             }};
@@ -257,6 +261,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
                 return new FreezeAction();
             case SetPriorityAction.NAME:
                 return SetPriorityActionTests.randomInstance();
+            case SearchableSnapshotAction.NAME:
+                return SearchableSnapshotActionTests.randomInstance();
             case UnfollowAction.NAME:
                 return new UnfollowAction();
             default:

+ 59 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/ilm/SearchableSnapshotActionTests.java

@@ -0,0 +1,59 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.client.ilm;
+
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.test.AbstractXContentTestCase;
+
+import java.io.IOException;
+
+import static org.hamcrest.Matchers.equalTo;
+
+public class SearchableSnapshotActionTests extends AbstractXContentTestCase<SearchableSnapshotAction> {
+
+    @Override
+    protected SearchableSnapshotAction doParseInstance(XContentParser parser) throws IOException {
+        return SearchableSnapshotAction.parse(parser);
+    }
+
+    @Override
+    protected SearchableSnapshotAction createTestInstance() {
+        return randomInstance();
+    }
+
+    static SearchableSnapshotAction randomInstance() {
+        return new SearchableSnapshotAction(randomAlphaOfLengthBetween(5, 10), randomBoolean());
+    }
+
+    @Override
+    protected boolean supportsUnknownFields() {
+        return false;
+    }
+
+    public void testEmptyOrNullRepository() {
+        {
+            IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new SearchableSnapshotAction(""));
+            assertThat(e.getMessage(), equalTo("the snapshot repository must be specified"));
+        }
+        {
+            IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new SearchableSnapshotAction(null));
+            assertThat(e.getMessage(), equalTo("the snapshot repository must be specified"));
+        }
+    }
+}