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

Service Layer changes for Recommission API #4320

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8c38c53
Initial commit for recommission service level changes
pranikum Aug 27, 2022
40d739b
Remove commented changes from service class
pranikum Aug 29, 2022
32d1499
Update Service layer to handle removal of recommission zone attribute
pranikum Sep 1, 2022
79561e1
Merge branch 'main' into recommission-service-level-support
pranikum Sep 7, 2022
f3b8dd8
Merge branch 'main' into recommission-service-level-support
pranikum Sep 7, 2022
ace11fe
Add change log and address comment.
pranikum Sep 7, 2022
3988e2d
Fix EOL Errors
pranikum Sep 7, 2022
fe3f01a
Fix spotless check
pranikum Sep 7, 2022
7ffb650
Remove unwanted files
pranikum Sep 7, 2022
bf0af0a
Remove unwanted files
pranikum Sep 7, 2022
1972243
Add unwanted deletion
pranikum Sep 7, 2022
2584d51
Add the correct gradle jar
pranikum Sep 7, 2022
e9d50a6
Fix spotless java check
pranikum Sep 7, 2022
4c6273b
Merge with latest
pranikum Sep 21, 2022
0b56861
Merge branch 'main' into recommission-service-level-support
pranikum Sep 21, 2022
95c41ff
Update Changelog
pranikum Sep 21, 2022
6e2ae8f
Add call to set weights
pranikum Sep 23, 2022
eaeefa6
Fix spotless check
pranikum Sep 23, 2022
8ca49e7
Fix spotless java check
pranikum Sep 23, 2022
97c4d32
Fix logger check
pranikum Sep 23, 2022
2d83698
Remove unused class
pranikum Sep 23, 2022
e7946d8
Add package info
pranikum Sep 24, 2022
98b4ac8
Merge change log to latest
pranikum Sep 24, 2022
fcf36cf
Merge branch 'main' into recommission-service-level-support
pranikum Sep 24, 2022
4f6543b
Add to changelog
pranikum Sep 24, 2022
02a96ba
add new line to package info
pranikum Sep 24, 2022
b2bfb31
Resolve conflict with latest
pranikum Sep 28, 2022
f3582e3
Merge branch 'main' into recommission-service-level-support
pranikum Sep 28, 2022
fe8f3b1
Take latest and add recommission changes
pranikum Sep 28, 2022
d52d48e
Remove unused class
pranikum Sep 28, 2022
93ee423
Merge changelog
pranikum Sep 29, 2022
45b98d3
Merge branch 'main' into recommission-service-level-support
pranikum Sep 29, 2022
56eca8f
Update changelog. Address minor changes
pranikum Sep 29, 2022
4d04395
Remove setting of weights. Just delete the attribute
pranikum Sep 30, 2022
c7c9f35
Update test cases. Call clearVotingConfigExclusion
pranikum Sep 30, 2022
0cf8def
Merge with latest
pranikum Oct 3, 2022
e203a57
Merge branch 'main' into recommission-service-level-support
pranikum Oct 3, 2022
7c14326
Merge with latest
pranikum Oct 3, 2022
f281473
PR comments
pranikum Oct 3, 2022
f22307f
PR comments
pranikum Oct 3, 2022
22a1d5e
Update method name
pranikum Oct 3, 2022
5227538
Update method name
pranikum Oct 3, 2022
b0cfef5
PR comments
pranikum Oct 5, 2022
c16ac3a
Resolve conflict with main
pranikum Oct 5, 2022
1b3471b
Merge branch 'main' into recommission-service-level-support
pranikum Oct 5, 2022
b1cf7a5
Merge changelog with latest
pranikum Oct 5, 2022
22cd77c
Update logger message
pranikum Oct 5, 2022
b3930c5
Fix log messages
pranikum Oct 5, 2022
5228119
Merge with main
pranikum Oct 6, 2022
4f58513
Merge branch 'main' into recommission-service-level-support
pranikum Oct 6, 2022
224dad4
Change log changes
pranikum Oct 6, 2022
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Support for HTTP/2 (server-side) ([#3847](https://github.com/opensearch-project/OpenSearch/pull/3847))
- BWC version 2.2.2 ([#4383](https://github.com/opensearch-project/OpenSearch/pull/4383))
- Support for labels on version bump PRs, skip label support for changelog verifier ([#4391](https://github.com/opensearch-project/OpenSearch/pull/4391))
- Recommission API changes for service layer ([#4320](https://github.com/opensearch-project/OpenSearch/pull/4320))
### Dependencies
- Bumps `org.gradle.test-retry` from 1.4.0 to 1.4.1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
pranikum marked this conversation as resolved.
Show resolved Hide resolved
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cluster.decommission;

import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
import org.opensearch.common.io.stream.Writeable;

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

/**
* {@link DecommissionAttribute} encapsulates information about decommissioned node attribute like attribute name, attribute value.
*
* @opensearch.internal
*/
public final class DecommissionAttribute implements Writeable {
pranikum marked this conversation as resolved.
Show resolved Hide resolved
private final String attributeName;
private final String attributeValue;

/**
* Constructs new decommission attribute name value pair
*
* @param attributeName attribute name
* @param attributeValue attribute value
*/
public DecommissionAttribute(String attributeName, String attributeValue) {
this.attributeName = attributeName;
this.attributeValue = attributeValue;
}

/**
* Returns attribute name
*
* @return attributeName
*/
public String attributeName() {
return this.attributeName;
}

/**
* Returns attribute value
*
* @return attributeValue
*/
public String attributeValue() {
return this.attributeValue;
}

public DecommissionAttribute(StreamInput in) throws IOException {
attributeName = in.readString();
attributeValue = in.readString();
}

/**
* Writes decommission attribute name value to stream output
*
* @param out stream output
*/
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(attributeName);
out.writeString(attributeValue);
}

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

DecommissionAttribute that = (DecommissionAttribute) o;

if (!attributeName.equals(that.attributeName)) return false;
return attributeValue.equals(that.attributeValue);
}

@Override
public int hashCode() {
return Objects.hash(attributeName, attributeValue);
}

@Override
public String toString() {
return "DecommissionAttribute{" + "attributeName='" + attributeName + '\'' + ", attributeValue='" + attributeValue + '\'' + '}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
pranikum marked this conversation as resolved.
Show resolved Hide resolved
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cluster.decommission;

import org.opensearch.OpenSearchException;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;

import java.io.IOException;

/**
* This exception is thrown whenever a failure occurs in decommission request @{@link DecommissionService}
*
* @opensearch.internal
*/
public class DecommissionFailedException extends OpenSearchException {

private final DecommissionAttribute decommissionAttribute;

public DecommissionFailedException(DecommissionAttribute decommissionAttribute, String msg) {
this(decommissionAttribute, msg, null);
}

public DecommissionFailedException(DecommissionAttribute decommissionAttribute, String msg, Throwable cause) {
super("[" + (decommissionAttribute == null ? "_na" : decommissionAttribute.toString()) + "] " + msg, cause);
this.decommissionAttribute = decommissionAttribute;
}

public DecommissionFailedException(StreamInput in) throws IOException {
super(in);
decommissionAttribute = new DecommissionAttribute(in);
}

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

/**
* Returns decommission attribute
*
* @return decommission attribute
*/
public DecommissionAttribute decommissionAttribute() {
return decommissionAttribute;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cluster.decommission;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.opensearch.action.ActionListener;
import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.ClusterStateUpdateTask;
import org.opensearch.cluster.ack.ClusterStateUpdateResponse;
import org.opensearch.cluster.metadata.DecommissionAttributeMetadata;
import org.opensearch.cluster.metadata.Metadata;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.common.Priority;
import org.opensearch.common.inject.Inject;

/**
* Service responsible for entire lifecycle of decommissioning and recommissioning an awareness attribute.
* <p>
* Whenever a cluster manager initiates operation to decommission an awareness attribute,
* the service makes the best attempt to perform the following task -
* <ul>
* <li>Remove cluster-manager eligible nodes from voting config [TODO - checks to avoid quorum loss scenarios]</li>
* <li>Initiates nodes decommissioning by adding custom metadata with the attribute and state as {@link DecommissionStatus#DECOMMISSION_INIT}</li>
* <li>Triggers weigh away for nodes having given awareness attribute to drain. This marks the decommission status as {@link DecommissionStatus#DECOMMISSION_IN_PROGRESS}</li>
* <li>Once weighed away, the service triggers nodes decommission</li>
* <li>Once the decommission is successful, the service clears the voting config and marks the status as {@link DecommissionStatus#DECOMMISSION_SUCCESSFUL}</li>
* <li>If service fails at any step, it would mark the status as {@link DecommissionStatus#DECOMMISSION_FAILED}</li>
* </ul>
*
* @opensearch.internal
*/
public class DecommissionService {

private static final Logger logger = LogManager.getLogger(DecommissionService.class);

private final ClusterService clusterService;

@Inject
public DecommissionService(ClusterService clusterService) {
this.clusterService = clusterService;
}

public void clearDecommissionStatus(final ActionListener<ClusterStateUpdateResponse> listener) {
clusterService.submitStateUpdateTask("delete_decommission_state", new ClusterStateUpdateTask(Priority.URGENT) {
@Override
public ClusterState execute(ClusterState currentState) {
return deleteDecommissionAttribute(currentState);
}

@Override
public void onFailure(String source, Exception e) {
logger.error(() -> new ParameterizedMessage("Failed to clear decommission attribute."), e);
pranikum marked this conversation as resolved.
Show resolved Hide resolved
listener.onFailure(e);
}

@Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
// Once the cluster state is processed we can try to recommission nodes by setting the weights for the zone.
// TODO Set the weights for the recommissioning zone.
listener.onResponse(new ClusterStateUpdateResponse(true));
pranikum marked this conversation as resolved.
Show resolved Hide resolved
}
});
}

ClusterState deleteDecommissionAttribute(final ClusterState currentState) {
logger.info("Delete decommission request received");
Metadata metadata = currentState.metadata();
Metadata.Builder mdBuilder = Metadata.builder(metadata);
mdBuilder.removeCustom(DecommissionAttributeMetadata.TYPE);
return ClusterState.builder(currentState).metadata(mdBuilder).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
pranikum marked this conversation as resolved.
Show resolved Hide resolved
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cluster.decommission;

/**
* An enumeration of the states during decommissioning and recommissioning.
*/
public enum DecommissionStatus {
/**
* Decommission process is initiated
*/
DECOMMISSION_INIT("decommission_init"),
/**
* Decommission process has started, decommissioned nodes should be weighed away
*/
DECOMMISSION_IN_PROGRESS("decommission_in_progress"),
/**
* Decommissioning awareness attribute completed
*/
DECOMMISSION_SUCCESSFUL("decommission_successful"),
/**
* Decommission request failed
*/
DECOMMISSION_FAILED("decommission_failed"),
/**
* Recommission request received, recommissioning process has started
*/
RECOMMISSION_IN_PROGRESS("recommission_in_progress"),
/**
* Recommission request failed. No nodes should fail to join the cluster with decommission exception
*/
RECOMMISSION_FAILED("recommission_failed");

private final String status;

DecommissionStatus(String status) {
this.status = status;
}

/**
* Returns status that represents the decommission state
*
* @return status
*/
public String status() {
return status;
}

/**
* Generate decommission status from given string
*
* @param status status in string
* @return status
*/
public static DecommissionStatus fromString(String status) {
if (status == null) {
throw new IllegalArgumentException("decommission status cannot be null");
}
if (status.equals(DECOMMISSION_INIT.status())) {
return DECOMMISSION_INIT;
} else if (status.equals(DECOMMISSION_IN_PROGRESS.status())) {
return DECOMMISSION_IN_PROGRESS;
} else if (status.equals(DECOMMISSION_SUCCESSFUL.status())) {
return DECOMMISSION_SUCCESSFUL;
} else if (status.equals(DECOMMISSION_FAILED.status())) {
return DECOMMISSION_FAILED;
} else if (status.equals(RECOMMISSION_IN_PROGRESS.status())) {
return RECOMMISSION_IN_PROGRESS;
} else if (status.equals(RECOMMISSION_FAILED.status())) {
return RECOMMISSION_FAILED;
}
throw new IllegalStateException("Decommission status [" + status + "] not recognized.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
pranikum marked this conversation as resolved.
Show resolved Hide resolved
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cluster.decommission;

import org.opensearch.OpenSearchException;
import org.opensearch.common.io.stream.StreamInput;

import java.io.IOException;

/**
* This exception is thrown if the node is decommissioned by @{@link DecommissionService}
* and this nodes needs to be removed from the cluster
*
* @opensearch.internal
*/
public class NodeDecommissionedException extends OpenSearchException {

public NodeDecommissionedException(String msg, Object... args) {
super(msg, args);
}

public NodeDecommissionedException(StreamInput in) throws IOException {
super(in);
}
}
Loading