Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add APIs to Maintenance Mode in ILM #31410

Merged
merged 7 commits into from
Jun 21, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@

public class IndexLifecycleMetadata implements XPackMetaDataCustom {
public static final String TYPE = "index_lifecycle";
public static final ParseField MAINTENANCE_MODE_FIELD = new ParseField("maintenance_mode");
public static final ParseField OPERATION_MODE_FIELD = new ParseField("operation_mode");
public static final ParseField POLICIES_FIELD = new ParseField("policies");
public static final IndexLifecycleMetadata EMPTY = new IndexLifecycleMetadata(Collections.emptySortedMap(), OperationMode.NORMAL);
public static final IndexLifecycleMetadata EMPTY = new IndexLifecycleMetadata(Collections.emptySortedMap(), OperationMode.RUNNING);

@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<IndexLifecycleMetadata, Void> PARSER = new ConstructingObjectParser<>(
Expand All @@ -47,15 +47,15 @@ public class IndexLifecycleMetadata implements XPackMetaDataCustom {
v -> {
throw new IllegalArgumentException("ordered " + POLICIES_FIELD.getPreferredName() + " are not supported");
}, POLICIES_FIELD);
PARSER.declareString(ConstructingObjectParser.constructorArg(), MAINTENANCE_MODE_FIELD);
PARSER.declareString(ConstructingObjectParser.constructorArg(), OPERATION_MODE_FIELD);
}

private final Map<String, LifecyclePolicyMetadata> policyMetadatas;
private final OperationMode maintenanceMode;
private final OperationMode operationMode;

public IndexLifecycleMetadata(Map<String, LifecyclePolicyMetadata> policies, OperationMode maintenanceMode) {
public IndexLifecycleMetadata(Map<String, LifecyclePolicyMetadata> policies, OperationMode operationMode) {
this.policyMetadatas = Collections.unmodifiableMap(policies);
this.maintenanceMode = maintenanceMode;
this.operationMode = operationMode;
}

public IndexLifecycleMetadata(StreamInput in) throws IOException {
Expand All @@ -65,7 +65,7 @@ public IndexLifecycleMetadata(StreamInput in) throws IOException {
policies.put(in.readString(), new LifecyclePolicyMetadata(in));
}
this.policyMetadatas = policies;
this.maintenanceMode = in.readEnum(OperationMode.class);
this.operationMode = in.readEnum(OperationMode.class);
}

@Override
Expand All @@ -75,15 +75,15 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(entry.getKey());
entry.getValue().writeTo(out);
}
out.writeEnum(maintenanceMode);
out.writeEnum(operationMode);
}

public Map<String, LifecyclePolicyMetadata> getPolicyMetadatas() {
return policyMetadatas;
}

public OperationMode getMaintenanceMode() {
return maintenanceMode;
public OperationMode getOperationMode() {
return operationMode;
}

public Map<String, LifecyclePolicy> getPolicies() {
Expand All @@ -99,7 +99,7 @@ public Diff<Custom> diff(Custom previousState) {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field(POLICIES_FIELD.getPreferredName(), policyMetadatas);
builder.field(MAINTENANCE_MODE_FIELD.getPreferredName(), maintenanceMode);
builder.field(OPERATION_MODE_FIELD.getPreferredName(), operationMode);
return builder;
}

Expand All @@ -120,7 +120,7 @@ public EnumSet<MetaData.XContentContext> context() {

@Override
public int hashCode() {
return Objects.hash(policyMetadatas, maintenanceMode);
return Objects.hash(policyMetadatas, operationMode);
}

@Override
Expand All @@ -133,7 +133,7 @@ public boolean equals(Object obj) {
}
IndexLifecycleMetadata other = (IndexLifecycleMetadata) obj;
return Objects.equals(policyMetadatas, other.policyMetadatas)
&& Objects.equals(maintenanceMode, other.maintenanceMode);
&& Objects.equals(operationMode, other.operationMode);
}

@Override
Expand All @@ -144,30 +144,30 @@ public String toString() {
public static class IndexLifecycleMetadataDiff implements NamedDiff<MetaData.Custom> {

final Diff<Map<String, LifecyclePolicyMetadata>> policies;
final OperationMode maintenanceMode;
final OperationMode operationMode;

IndexLifecycleMetadataDiff(IndexLifecycleMetadata before, IndexLifecycleMetadata after) {
this.policies = DiffableUtils.diff(before.policyMetadatas, after.policyMetadatas, DiffableUtils.getStringKeySerializer());
this.maintenanceMode = after.maintenanceMode;
this.operationMode = after.operationMode;
}

public IndexLifecycleMetadataDiff(StreamInput in) throws IOException {
this.policies = DiffableUtils.readJdkMapDiff(in, DiffableUtils.getStringKeySerializer(), LifecyclePolicyMetadata::new,
IndexLifecycleMetadataDiff::readLifecyclePolicyDiffFrom);
this.maintenanceMode = in.readEnum(OperationMode.class);
this.operationMode = in.readEnum(OperationMode.class);
}

@Override
public MetaData.Custom apply(MetaData.Custom part) {
TreeMap<String, LifecyclePolicyMetadata> newPolicies = new TreeMap<>(
policies.apply(((IndexLifecycleMetadata) part).policyMetadatas));
return new IndexLifecycleMetadata(newPolicies, this.maintenanceMode);
return new IndexLifecycleMetadata(newPolicies, this.operationMode);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
policies.writeTo(out);
out.writeEnum(maintenanceMode);
out.writeEnum(operationMode);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,31 @@ public enum OperationMode {
/**
* This represents a state where no policies are executed
*/
MAINTENANCE {
STOPPED {
@Override
public boolean isValidChange(OperationMode nextMode) {
return nextMode == NORMAL;
return nextMode == RUNNING;
}
},

/**
* this representes a state where only sensitive actions (like {@link ShrinkAction}) will be executed
* until they finish, at which point the operation mode will move to maintenance mode.
* this represents a state where only sensitive actions (like {@link ShrinkAction}) will be executed
* until they finish, at which point the operation mode will move to <code>STOPPED</code>.
*/
MAINTENANCE_REQUESTED {
STOPPING {
@Override
public boolean isValidChange(OperationMode nextMode) {
return nextMode == NORMAL || nextMode == MAINTENANCE;
return nextMode == RUNNING || nextMode == STOPPED;
}
},

/**
* Normal operation where all policies are executed as normal.
*/
NORMAL {
RUNNING {
@Override
public boolean isValidChange(OperationMode nextMode) {
return nextMode == MAINTENANCE_REQUESTED;
return nextMode == STOPPING;
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle.action;

import org.elasticsearch.action.Action;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;

import java.io.IOException;
import java.util.Objects;

public class GetOperationModeStatusAction extends Action<GetOperationModeStatusAction.Response> {
public static final GetOperationModeStatusAction INSTANCE = new GetOperationModeStatusAction();
public static final String NAME = "cluster:admin/xpack/index_lifecycle/operation_mode/get";

protected GetOperationModeStatusAction() {
super(NAME);
}

@Override
public Response newResponse() {
return new Response();
}

public static class Response extends ActionResponse implements ToXContentObject {

private OperationMode mode;

public Response() {
}

public Response(OperationMode mode) {
this.mode = mode;
}

public OperationMode getMode() {
return mode;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("operation_mode", mode);
builder.endObject();
return builder;
}

@Override
public void readFrom(StreamInput in) throws IOException {
mode = in.readEnum(OperationMode.class);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeEnum(mode);
}

@Override
public int hashCode() {
return Objects.hash(mode);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
Response other = (Response) obj;
return Objects.equals(mode, other.mode);
}

@Override
public String toString() {
return Strings.toString(this, true, true);
}

}

public static class Request extends AcknowledgedRequest<Request> {

public Request() {
}

@Override
public ActionRequestValidationException validate() {
return null;
}

@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle.action;

import org.elasticsearch.action.Action;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;

import java.io.IOException;
import java.util.Objects;

public class SetOperationModeAction extends Action<SetOperationModeAction.Response> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe to be consistent with the naming of the other APIs in Elasticsearch we should call this Put instead of Set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this felt weird since I am not PUTing a resty resource, especially since it is being exposed by APIs that do not necessarily ever set a specific operation-mode directly, like STOPPED.

Given all of ^, I also view this as a pedantic argument that loses in the battle of consistency 😄. So I will rename

public static final SetOperationModeAction INSTANCE = new SetOperationModeAction();
public static final String NAME = "cluster:admin/xpack/index_lifecycle/operation_mode/set";

protected SetOperationModeAction() {
super(NAME);
}

@Override
public Response newResponse() {
return new Response();
}

public static class Response extends AcknowledgedResponse implements ToXContentObject {

public Response() {
}

public Response(boolean acknowledged) {
super(acknowledged);
}
}

public static class Request extends AcknowledgedRequest<Request> {

private OperationMode mode;

public Request(OperationMode mode) {
this.mode = mode;
}

public Request() {
}

public OperationMode getMode() {
return mode;
}

@Override
public ActionRequestValidationException validate() {
if (mode == OperationMode.STOPPED) {
ActionRequestValidationException exception = new ActionRequestValidationException();
exception.addValidationError("cannot directly stop index-lifecycle");
return exception;
}
return null;
}

@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
mode = in.readEnum(OperationMode.class);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeEnum(mode);
}

@Override
public int hashCode() {
return Objects.hash(mode);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
Request other = (Request) obj;
return Objects.equals(mode, other.mode);
}
}

}
Loading