Skip to content

Commit

Permalink
HLRC: Add ILM Status to HLRC (#33283)
Browse files Browse the repository at this point in the history
Adds support for the Index Lifecycle Management Status to the Java
High-Level Rest Client.

Relates to #33100
  • Loading branch information
jakelandis committed Sep 5, 2018
1 parent 023e1bf commit 8b8ff2b
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 21 deletions.
Expand Up @@ -22,6 +22,8 @@
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusResponse;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
Expand Down Expand Up @@ -169,6 +171,35 @@ public AcknowledgedResponse stopILM(StopILMRequest request, RequestOptions optio
AcknowledgedResponse::fromXContent, emptySet());
}

/**
* Get the status of index lifecycle management
* See <a href="https://fix-me-when-we-have-docs.com">
* the docs</a> for more.
*
* @param request the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
*/
public LifecycleManagementStatusResponse lifecycleManagementStatus(LifecycleManagementStatusRequest request, RequestOptions options)
throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::lifecycleManagementStatus, options,
LifecycleManagementStatusResponse::fromXContent, emptySet());
}

/**
* Asynchronously get the status of index lifecycle management
* See <a href="https://fix-me-when-we-have-docs.com">
* the docs</a> for more.
*
* @param request the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
*/
public void lifecycleManagementStatusAsync(LifecycleManagementStatusRequest request, RequestOptions options,
ActionListener<LifecycleManagementStatusResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::lifecycleManagementStatus, options,
LifecycleManagementStatusResponse::fromXContent, listener, emptySet());
}

/**
* Asynchronously stop the Index Lifecycle Management feature.
* See <a href="https://fix-me-when-we-have-docs.com">
Expand Down
Expand Up @@ -86,6 +86,7 @@
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
import org.elasticsearch.client.security.RefreshPolicy;
Expand Down Expand Up @@ -1266,6 +1267,18 @@ static Request stopILM(StopILMRequest stopILMRequest) {
return request;
}

static Request lifecycleManagementStatus(LifecycleManagementStatusRequest lifecycleManagementStatusRequest){
Request request = new Request(HttpGet.METHOD_NAME,
new EndpointBuilder()
.addPathPartAsIs("_ilm")
.addPathPartAsIs("status")
.build());
Params params = new Params(request);
params.withMasterTimeout(lifecycleManagementStatusRequest.masterNodeTimeout());
params.withTimeout(lifecycleManagementStatusRequest.timeout());
return request;
}

static Request explainLifecycle(ExplainLifecycleRequest explainLifecycleRequest) {
String[] indices = explainLifecycleRequest.indices() == null ? Strings.EMPTY_ARRAY : explainLifecycleRequest.indices();
Request request = new Request(HttpGet.METHOD_NAME,
Expand Down
Expand Up @@ -26,7 +26,7 @@
* Please note, any requests that use a ackTimeout should set timeout as they
* represent the same backing field on the server.
*/
public class TimedRequest implements Validatable {
public abstract class TimedRequest implements Validatable {

public static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueSeconds(30);
public static final TimeValue DEFAULT_MASTER_TIMEOUT = TimeValue.timeValueSeconds(30);
Expand All @@ -36,7 +36,6 @@ public class TimedRequest implements Validatable {

public void setTimeout(TimeValue timeout) {
this.timeout = timeout;

}

public void setMasterTimeout(TimeValue masterTimeout) {
Expand Down
@@ -0,0 +1,28 @@
/*
* 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.indexlifecycle;

import org.elasticsearch.client.TimedRequest;

/**
* A {@link TimedRequest} to get the current status of index lifecycle management.
*/
public class LifecycleManagementStatusRequest extends TimedRequest {
}
@@ -0,0 +1,68 @@
/*
* 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.indexlifecycle;

import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;

import java.util.Objects;

/**
* The current status of index lifecycle management. See {@link OperationMode} for available statuses.
*/
public class LifecycleManagementStatusResponse {

private final OperationMode operationMode;
private static final String OPERATION_MODE = "operation_mode";
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<LifecycleManagementStatusResponse, Void> PARSER = new ConstructingObjectParser<>(
OPERATION_MODE, a -> new LifecycleManagementStatusResponse((String) a[0]));

static {
PARSER.declareString(ConstructingObjectParser.constructorArg(), new ParseField(OPERATION_MODE));
}

//package private for testing
LifecycleManagementStatusResponse(String operationMode) {
this.operationMode = OperationMode.fromString(operationMode);
}

public OperationMode getOperationMode() {
return operationMode;
}

public static LifecycleManagementStatusResponse fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LifecycleManagementStatusResponse that = (LifecycleManagementStatusResponse) o;
return operationMode == that.operationMode;
}

@Override
public int hashCode() {
return Objects.hash(operationMode);
}
}
Expand Up @@ -20,6 +20,9 @@

import org.elasticsearch.action.admin.indices.shrink.ShrinkAction;

import java.util.EnumSet;
import java.util.Locale;

/**
* Enum representing the different modes that Index Lifecycle Service can operate in.
*/
Expand Down Expand Up @@ -56,4 +59,10 @@ public boolean isValidChange(OperationMode nextMode) {
};

public abstract boolean isValidChange(OperationMode nextMode);

static OperationMode fromString(String string) {
return EnumSet.allOf(OperationMode.class).stream()
.filter(e -> string.equalsIgnoreCase(e.name())).findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format(Locale.ROOT, "%s is not a valid operation_mode", string)));
}
}
Expand Up @@ -19,21 +19,23 @@

package org.elasticsearch.client;

import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.indexlifecycle.AllocateAction;
import org.elasticsearch.client.indexlifecycle.DeleteAction;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.ForceMergeAction;
import org.elasticsearch.client.indexlifecycle.LifecycleAction;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusResponse;
import org.elasticsearch.client.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.client.indexlifecycle.OperationMode;
import org.elasticsearch.client.indexlifecycle.Phase;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RolloverAction;
import org.elasticsearch.client.indexlifecycle.ShrinkAction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
Expand Down Expand Up @@ -88,35 +90,33 @@ public void testStartStopILM() throws Exception {
createIndex("baz", Settings.builder().put("index.lifecycle.name", "eggplant").build());
createIndex("squash", Settings.EMPTY);

// TODO: NORELEASE convert this to using the high level client once
// there are APIs for it
Request statusReq = new Request("GET", "/_ilm/status");
Response statusResponse = client().performRequest(statusReq);
String statusResponseString = EntityUtils.toString(statusResponse.getEntity());
assertEquals("{\"operation_mode\":\"RUNNING\"}", statusResponseString);
LifecycleManagementStatusRequest statusRequest = new LifecycleManagementStatusRequest();
LifecycleManagementStatusResponse statusResponse = execute(
statusRequest,
highLevelClient().indexLifecycle()::lifecycleManagementStatus,
highLevelClient().indexLifecycle()::lifecycleManagementStatusAsync);
assertEquals(statusResponse.getOperationMode(), OperationMode.RUNNING);

StopILMRequest stopReq = new StopILMRequest();
AcknowledgedResponse stopResponse = execute(stopReq, highLevelClient().indexLifecycle()::stopILM,
highLevelClient().indexLifecycle()::stopILMAsync);
assertTrue(stopResponse.isAcknowledged());

// TODO: NORELEASE convert this to using the high level client once there are APIs for it
statusReq = new Request("GET", "/_ilm/status");
statusResponse = client().performRequest(statusReq);
statusResponseString = EntityUtils.toString(statusResponse.getEntity());
assertThat(statusResponseString,
Matchers.anyOf(equalTo("{\"operation_mode\":\"STOPPING\"}"), equalTo("{\"operation_mode\":\"STOPPED\"}")));

statusResponse = execute(statusRequest, highLevelClient().indexLifecycle()::lifecycleManagementStatus,
highLevelClient().indexLifecycle()::lifecycleManagementStatusAsync);
assertThat(statusResponse.getOperationMode(),
Matchers.anyOf(equalTo(OperationMode.STOPPING),
equalTo(OperationMode.STOPPED)));

StartILMRequest startReq = new StartILMRequest();
AcknowledgedResponse startResponse = execute(startReq, highLevelClient().indexLifecycle()::startILM,
highLevelClient().indexLifecycle()::startILMAsync);
assertTrue(startResponse.isAcknowledged());

// TODO: NORELEASE convert this to using the high level client once there are APIs for it
statusReq = new Request("GET", "/_ilm/status");
statusResponse = client().performRequest(statusReq);
statusResponseString = EntityUtils.toString(statusResponse.getEntity());
assertEquals("{\"operation_mode\":\"RUNNING\"}", statusResponseString);
statusResponse = execute(statusRequest, highLevelClient().indexLifecycle()::lifecycleManagementStatus,
highLevelClient().indexLifecycle()::lifecycleManagementStatusAsync);
assertEquals(statusResponse.getOperationMode(), OperationMode.RUNNING);
}

public void testExplainLifecycle() throws Exception {
Expand Down
Expand Up @@ -94,6 +94,7 @@
import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestConverters.EndpointBuilder;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
import org.elasticsearch.client.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
Expand Down Expand Up @@ -2764,6 +2765,18 @@ public void testStopILM() throws Exception {
assertThat(request.getParameters(), equalTo(expectedParams));
}

public void testLifecycleManagementStatus() throws Exception {
LifecycleManagementStatusRequest req = new LifecycleManagementStatusRequest();
Map<String, String> expectedParams = new HashMap<>();
setRandomMasterTimeout(req::setMasterTimeout, TimedRequest.DEFAULT_TIMEOUT, expectedParams);
setRandomTimeoutTimeValue(req::setTimeout, TimedRequest.DEFAULT_MASTER_TIMEOUT, expectedParams);

Request request = RequestConverters.lifecycleManagementStatus(req);
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME));
assertThat(request.getEndpoint(), equalTo("/_ilm/status"));
assertThat(request.getParameters(), equalTo(expectedParams));
}

public void testExplainLifecycle() throws Exception {
ExplainLifecycleRequest req = new ExplainLifecycleRequest();
String[] indices = rarely() ? null : randomIndicesNames(0, 10);
Expand Down
@@ -0,0 +1,42 @@
/*
* 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;

import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.ESTestCase;

public class TimedRequestTests extends ESTestCase {

public void testDefaults() {
TimedRequest timedRequest = new TimedRequest(){};
assertEquals(timedRequest.timeout(), TimedRequest.DEFAULT_TIMEOUT);
assertEquals(timedRequest.masterNodeTimeout(), TimedRequest.DEFAULT_MASTER_TIMEOUT);
}

public void testNonDefaults() {
TimedRequest timedRequest = new TimedRequest(){};
TimeValue timeout = TimeValue.timeValueSeconds(randomIntBetween(0, 1000));
TimeValue masterTimeout = TimeValue.timeValueSeconds(randomIntBetween(0,1000));
timedRequest.setTimeout(timeout);
timedRequest.setMasterTimeout(masterTimeout);
assertEquals(timedRequest.timeout(), timeout);
assertEquals(timedRequest.masterNodeTimeout(), masterTimeout);
}
}

0 comments on commit 8b8ff2b

Please sign in to comment.