This is an automated email from the ASF dual-hosted git repository. xyuanlu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/helix.git
commit 7558822c02647d7ff2ac09f541ddf5dde8046f57 Author: Grant Paláu Spencer <gspen...@linkedin.com> AuthorDate: Tue Nov 14 00:05:34 2023 -0800 Expose Evacuate Finished API in Helix-Rest (#2694) --- .../rest/server/resources/AbstractResource.java | 3 +- .../resources/helix/PerInstanceAccessor.java | 10 +++++++ .../helix/rest/server/TestPerInstanceAccessor.java | 33 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/AbstractResource.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/AbstractResource.java index 64fbaff41..ce3d27273 100644 --- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/AbstractResource.java +++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/AbstractResource.java @@ -88,7 +88,8 @@ public class AbstractResource { setInstanceOperation, // TODO: Name is just a place holder, may change in future canCompleteSwap, completeSwapIfPossible, - onDemandRebalance + onDemandRebalance, + isEvacuateFinished } @Context diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java index b1b4f8264..f380975a3 100644 --- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java +++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java @@ -477,6 +477,16 @@ public class PerInstanceAccessor extends AbstractHelixResource { OBJECT_MAPPER.getTypeFactory() .constructCollectionType(List.class, String.class))); break; + case isEvacuateFinished: + boolean evacuateFinished; + try { + evacuateFinished = admin.isEvacuateFinished(clusterId, instanceName); + } catch (HelixException e) { + LOG.error(String.format("Encountered error when checking if evacuation finished for cluster: " + + "{}, instance: {}", clusterId, instanceName), e); + return serverError(e); + } + return OK(OBJECT_MAPPER.writeValueAsString(Map.of("successful", evacuateFinished))); default: LOG.error("Unsupported command :" + command); return badRequest("Unsupported command :" + command); diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java index a8675202a..a1f46cce9 100644 --- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java +++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java @@ -521,6 +521,39 @@ public class TestPerInstanceAccessor extends AbstractTestClass { OBJECT_MAPPER.readValue(completeSwapIfPossibleResponse.readEntity(String.class), Map.class); Assert.assertFalse((boolean) responseMap.get("successful")); + // test isEvacuateFinished on instance with EVACUATE but has currentState + new JerseyUriRequestBuilder("clusters/{}/instances/{}?command=setInstanceOperation&instanceOperation=EVACUATE") + .format(CLUSTER_NAME, INSTANCE_NAME).post(this, entity); + instanceConfig = _configAccessor.getInstanceConfig(CLUSTER_NAME, INSTANCE_NAME); + Assert.assertEquals( + instanceConfig.getInstanceOperation(), InstanceConstants.InstanceOperation.EVACUATE.toString()); + + Response response = new JerseyUriRequestBuilder("clusters/{}/instances/{}?command=isEvacuateFinished") + .format(CLUSTER_NAME, INSTANCE_NAME).post(this, entity); + Map<String, Boolean> evacuateFinishedresult = OBJECT_MAPPER.readValue(response.readEntity(String.class), Map.class); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + Assert.assertFalse(evacuateFinishedresult.get("successful")); + + // test isEvacuateFinished on instance with EVACUATE and no currentState + // Create new instance so no currentState or messages assigned to it + String test_instance_name = INSTANCE_NAME + "_foo"; + InstanceConfig newInstanceConfig = new InstanceConfig(test_instance_name); + Entity instanceEntity = Entity.entity(OBJECT_MAPPER.writeValueAsString(newInstanceConfig.getRecord()), + MediaType.APPLICATION_JSON_TYPE); + new JerseyUriRequestBuilder("clusters/{}/instances/{}").format(CLUSTER_NAME, test_instance_name) + .put(this, instanceEntity); + + new JerseyUriRequestBuilder("clusters/{}/instances/{}?command=setInstanceOperation&instanceOperation=EVACUATE") + .format(CLUSTER_NAME, test_instance_name).post(this, entity); + instanceConfig = _configAccessor.getInstanceConfig(CLUSTER_NAME, test_instance_name); + Assert.assertEquals( + instanceConfig.getInstanceOperation(), InstanceConstants.InstanceOperation.EVACUATE.toString()); + + response = new JerseyUriRequestBuilder("clusters/{}/instances/{}?command=isEvacuateFinished") + .format(CLUSTER_NAME, test_instance_name).post(this, entity); + evacuateFinishedresult = OBJECT_MAPPER.readValue(response.readEntity(String.class), Map.class); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + Assert.assertTrue(evacuateFinishedresult.get("successful")); System.out.println("End test :" + TestHelper.getTestMethodName()); }