REST support for batch API enable and disable

Project: http://git-wip-us.apache.org/repos/asf/helix/repo
Commit: http://git-wip-us.apache.org/repos/asf/helix/commit/d03dca1e
Tree: http://git-wip-us.apache.org/repos/asf/helix/tree/d03dca1e
Diff: http://git-wip-us.apache.org/repos/asf/helix/diff/d03dca1e

Branch: refs/heads/master
Commit: d03dca1ee360d1ac8dd3d04bbcf50d8e5623c0e7
Parents: 62752b2
Author: Junkai Xue <[email protected]>
Authored: Wed Nov 15 17:31:00 2017 -0800
Committer: Junkai Xue <[email protected]>
Committed: Wed Jan 24 18:31:30 2018 -0800

----------------------------------------------------------------------
 .../helix/manager/zk/ZkBaseDataAccessor.java    |  6 ++-
 .../rest/server/resources/InstanceAccessor.java | 41 ++++++++++++++++++++
 .../helix/rest/server/TestInstanceAccessor.java | 29 ++++++++++++++
 3 files changed, 74 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/helix/blob/d03dca1e/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
----------------------------------------------------------------------
diff --git 
a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java 
b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
index 0ccda43..f8678e5 100644
--- 
a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
+++ 
b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
@@ -392,8 +392,10 @@ public class ZkBaseDataAccessor<T> implements 
BaseDataAccessor<T> {
           nodeFailToRead.append(paths + ",");
         }
       }
-      LOG.warn(String.format("Fail to read nodes for paths : %s",
-          nodeFailToRead.toString().substring(nodeFailToRead.length() - 1)));
+      if (nodeFailToRead.length() > 0) {
+        LOG.warn(String.format("Fail to read nodes for paths : %s",
+            nodeFailToRead.toString().substring(nodeFailToRead.length() - 1)));
+      }
       return records;
     } finally {
       long endT = System.nanoTime();

http://git-wip-us.apache.org/repos/asf/helix/blob/d03dca1e/helix-rest/src/main/java/org/apache/helix/rest/server/resources/InstanceAccessor.java
----------------------------------------------------------------------
diff --git 
a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/InstanceAccessor.java
 
b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/InstanceAccessor.java
index 5b25c3e..0099097 100644
--- 
a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/InstanceAccessor.java
+++ 
b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/InstanceAccessor.java
@@ -112,6 +112,47 @@ public class InstanceAccessor extends AbstractResource {
     return JSONRepresentation(root);
   }
 
+  @POST
+  public Response updateInstances(@PathParam("clusterId") String clusterId,
+      @QueryParam("command") String command, String content) {
+    Command cmd;
+    try {
+      cmd = Command.valueOf(command);
+    } catch (Exception e) {
+      return badRequest("Invalid command : " + command);
+    }
+
+    HelixAdmin admin = getHelixAdmin();
+    try {
+      JsonNode node = null;
+      if (content.length() != 0) {
+        node = OBJECT_MAPPER.readTree(content);
+      }
+      if (node == null) {
+        return badRequest("Invalid input for content : " + content);
+      }
+      List<String> enableInstances = OBJECT_MAPPER
+          .readValue(node.get(InstanceProperties.instances.name()).toString(),
+              
OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, 
String.class));
+      switch (cmd) {
+      case enable:
+        admin.enableInstance(clusterId, enableInstances, true);
+
+        break;
+      case disable:
+        admin.enableInstance(clusterId, enableInstances, false);
+        break;
+      default:
+        _logger.error("Unsupported command :" + command);
+        return badRequest("Unsupported command :" + command);
+      }
+    } catch (Exception e) {
+      _logger.error("Failed in updating instances : " + content, e);
+      return badRequest(e.getMessage());
+    }
+    return OK();
+  }
+
   @GET
   @Path("{instanceName}")
   public Response getInstance(@PathParam("clusterId") String clusterId,

http://git-wip-us.apache.org/repos/asf/helix/blob/d03dca1e/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstanceAccessor.java
----------------------------------------------------------------------
diff --git 
a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstanceAccessor.java
 
b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstanceAccessor.java
index 5b3f605..7e1b4cb 100644
--- 
a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstanceAccessor.java
+++ 
b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstanceAccessor.java
@@ -23,6 +23,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.ws.rs.client.Entity;
@@ -30,6 +32,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.helix.HelixException;
 import org.apache.helix.TestHelper;
+import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.rest.server.resources.AbstractResource;
 import org.apache.helix.rest.server.resources.InstanceAccessor;
@@ -133,5 +136,31 @@ public class TestInstanceAccessor extends 
AbstractTestClass {
         Response.Status.OK.getStatusCode());
     Assert.assertEquals(_configAccessor.getInstanceConfig(CLUSTER_NAME, 
INSTANCE_NAME).getTags(),
         ImmutableList.of("tag2"));
+
+    // Batch disable instances
+    List<String> instancesToDisable = Arrays.asList(
+        new String[] { CLUSTER_NAME + "localhost_12918", CLUSTER_NAME + 
"localhost_12919",
+            CLUSTER_NAME + "localhost_12920"
+        });
+    entity = Entity.entity(OBJECT_MAPPER.writeValueAsString(
+        ImmutableMap.of(InstanceAccessor.InstanceProperties.instances.name(), 
instancesToDisable)),
+        MediaType.APPLICATION_JSON_TYPE);
+    post("clusters/" + CLUSTER_NAME + "/instances", ImmutableMap.of("command", 
"disable"), entity,
+        Response.Status.OK.getStatusCode());
+    ClusterConfig clusterConfig = 
_configAccessor.getClusterConfig(CLUSTER_NAME);
+    Assert.assertEquals(clusterConfig.getDisabledInstances().keySet(),
+        new HashSet<>(instancesToDisable));
+
+    instancesToDisable = Arrays
+        .asList(new String[] { CLUSTER_NAME + "localhost_12918", CLUSTER_NAME 
+ "localhost_12920"
+        });
+    entity = Entity.entity(OBJECT_MAPPER.writeValueAsString(
+        ImmutableMap.of(InstanceAccessor.InstanceProperties.instances.name(), 
instancesToDisable)),
+        MediaType.APPLICATION_JSON_TYPE);
+    post("clusters/" + CLUSTER_NAME + "/instances", ImmutableMap.of("command", 
"enable"), entity,
+        Response.Status.OK.getStatusCode());
+    clusterConfig = _configAccessor.getClusterConfig(CLUSTER_NAME);
+    Assert.assertEquals(clusterConfig.getDisabledInstances().keySet(),
+        new HashSet<>(Arrays.asList(CLUSTER_NAME + "localhost_12919")));
   }
 }

Reply via email to