Repository: helix Updated Branches: refs/heads/helix-0.6.x aa2e968f7 -> 9a5dbeaa6
[HELIX-546] Add REST API for Helix job queue management - third part, rb=28620 Project: http://git-wip-us.apache.org/repos/asf/helix/repo Commit: http://git-wip-us.apache.org/repos/asf/helix/commit/9a5dbeaa Tree: http://git-wip-us.apache.org/repos/asf/helix/tree/9a5dbeaa Diff: http://git-wip-us.apache.org/repos/asf/helix/diff/9a5dbeaa Branch: refs/heads/helix-0.6.x Commit: 9a5dbeaa624715e76486ae908eab48e503d28ceb Parents: aa2e968 Author: zzhang <[email protected]> Authored: Tue Dec 2 18:26:02 2014 -0800 Committer: zzhang <[email protected]> Committed: Tue Dec 2 18:26:02 2014 -0800 ---------------------------------------------------------------------- .../helix/webapp/resources/ClusterResource.java | 54 +++++++++---- .../webapp/resources/ClustersResource.java | 31 ++++++-- .../helix/webapp/resources/ConfigResource.java | 79 +++++++++++++------- .../webapp/resources/ConstraintResource.java | 76 ++++++++++++------- .../webapp/resources/ControllerResource.java | 42 ++++++++--- .../webapp/resources/IdealStateResource.java | 70 +++++++++++++++-- .../webapp/resources/JobQueueResource.java | 31 +++++++- .../webapp/resources/JobQueuesResource.java | 20 +++++ .../helix/webapp/resources/JobResource.java | 10 +++ .../helix/webapp/resources/ResourceUtil.java | 5 +- 10 files changed, 318 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java index b22d801..ea8b8db 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java @@ -20,9 +20,7 @@ package org.apache.helix.webapp.resources; */ import java.io.IOException; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.apache.helix.HelixDataAccessor; import org.apache.helix.HelixException; @@ -31,44 +29,56 @@ import org.apache.helix.ZNRecord; import org.apache.helix.manager.zk.ZkClient; import org.apache.helix.model.LiveInstance; import org.apache.helix.tools.ClusterSetup; -import org.apache.helix.webapp.RestAdminApplication; +import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.restlet.data.MediaType; -import org.restlet.data.Method; import org.restlet.data.Status; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code> "/clusters/{clusterName}" + * <p> + * <li>GET list cluster information + * <li>POST activate/deactivate a cluster in distributed controller mode + * <li>DELETE remove a cluster + */ public class ClusterResource extends ServerResource { - + private final static Logger LOG = Logger.getLogger(ClusterResource.class); + public ClusterResource() { getVariants().add(new Variant(MediaType.TEXT_PLAIN)); getVariants().add(new Variant(MediaType.APPLICATION_JSON)); setNegotiated(false); } + /** + * List cluster information + * <p> + * Usage: <code> curl http://{host:port}/clusters/{clusterName} + */ @Override public Representation get() { StringRepresentation presentation = null; try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); presentation = getClusterRepresentation(clusterName); - } - - catch (Exception e) { + } catch (Exception e) { String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e); presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON); - e.printStackTrace(); + LOG.error("Exception in get cluster", e); } return presentation; } StringRepresentation getClusterRepresentation(String clusterName) throws JsonGenerationException, JsonMappingException, IOException { - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); List<String> instances = setupTool.getClusterManagementTool().getInstancesInCluster(clusterName); @@ -100,12 +110,20 @@ public class ClusterResource extends ServerResource { return representation; } + /** + * Activate/deactivate a cluster in distributed controller mode + * <p> + * Usage: <code> curl -d 'jsonParameters= + * {"command":"activateCluster","grandCluster":"{controllerCluster}","enabled":"{true/false}"}' -H + * "Content-Type: application/json" http://{host:port}/clusters/{clusterName}} + */ @Override public Representation post(Representation entity) { try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); JsonParameters jsonParameters = new JsonParameters(entity); @@ -143,12 +161,18 @@ public class ClusterResource extends ServerResource { return getResponseEntity(); } + /** + * Remove a cluster + * <p> + * Usage: <code> curl -X DELETE http://{host:port}/clusters/{clusterName} + */ @Override public Representation delete() { try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); setupTool.deleteCluster(clusterName); getResponse().setStatus(Status.SUCCESS_OK); http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java index 4b12054..f823bf8 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java @@ -26,7 +26,6 @@ import org.apache.helix.HelixException; import org.apache.helix.ZNRecord; import org.apache.helix.manager.zk.ZkClient; import org.apache.helix.tools.ClusterSetup; -import org.apache.helix.webapp.RestAdminApplication; import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; @@ -37,6 +36,12 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code> "/clusters" + * <p> + * <li>GET list all Helix clusters + * <li>POST add a new cluster + */ public class ClustersResource extends ServerResource { private final static Logger LOG = Logger.getLogger(ClustersResource.class); @@ -44,27 +49,31 @@ public class ClustersResource extends ServerResource { getVariants().add(new Variant(MediaType.TEXT_PLAIN)); getVariants().add(new Variant(MediaType.APPLICATION_JSON)); setNegotiated(false); - // handle(request,response); } + /** + * List all Helix clusters + * <p> + * Usage: <code> curl http://{host:port}/clusters + */ @Override public Representation get() { StringRepresentation presentation = null; try { presentation = getClustersRepresentation(); } catch (Exception e) { - LOG.error("", e); + LOG.error("Exception in get all clusters", e); String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e); presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON); - - e.printStackTrace(); } return presentation; } StringRepresentation getClustersRepresentation() throws JsonGenerationException, JsonMappingException, IOException { - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); + ClusterSetup setupTool = new ClusterSetup(zkClient); List<String> clusters = setupTool.getClusterManagementTool().getClusters(); @@ -77,6 +86,12 @@ public class ClustersResource extends ServerResource { return representation; } + /** + * Add a new Helix cluster + * <p> + * Usage: <code> curl -d 'jsonParameters={"command":"addCluster","clusterName":"{clusterName}"}' -H + * "Content-Type: application/json" http://{host:port}/clusters + */ @Override public Representation post(Representation entity) { try { @@ -90,7 +105,7 @@ public class ClustersResource extends ServerResource { jsonParameters.verifyCommand(ClusterSetup.addCluster); ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); setupTool.addCluster(jsonParameters.getParameter(JsonParameters.CLUSTER_NAME), false); } else { @@ -111,6 +126,6 @@ public class ClustersResource extends ServerResource { @Override public Representation delete() { - return null; + return null; } } http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java index 3c384d4..575df9f 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java @@ -33,9 +33,6 @@ import org.apache.helix.model.builder.HelixConfigScopeBuilder; import org.apache.helix.tools.ClusterSetup; import org.apache.helix.webapp.RestAdminApplication; import org.apache.log4j.Logger; -import org.restlet.Context; -import org.restlet.Request; -import org.restlet.Response; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.representation.Representation; @@ -43,6 +40,12 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code> "/clusters/{clusterName}/configs" + * <p> + * <li>GET get scoped configs + * <li>POST set/remove scoped configs + */ public class ConfigResource extends ServerResource { private final static Logger LOG = Logger.getLogger(ConfigResource.class); @@ -76,15 +79,14 @@ public class ConfigResource extends ServerResource { StringRepresentation getConfigKeys(ConfigScopeProperty scopeProperty, String... keys) throws Exception { StringRepresentation representation = null; - // String clusterName = getValue("clusterName"); - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); HelixAdmin admin = setupTool.getClusterManagementTool(); ZNRecord record = new ZNRecord(scopeProperty + " Config"); HelixConfigScope scope = new HelixConfigScopeBuilder(scopeProperty, keys).build(); - // List<String> configKeys = admin.getConfigKeys(scopeProperty, clusterName, keys); List<String> configKeys = admin.getConfigKeys(scope); record.setListField(scopeProperty.toString(), configKeys); @@ -95,12 +97,12 @@ public class ConfigResource extends ServerResource { return representation; } - StringRepresentation getConfigs(// ConfigScope scope, - ConfigScopeProperty scopeProperty, String... keys) throws Exception { + StringRepresentation getConfigs(ConfigScopeProperty scopeProperty, String... keys) + throws Exception { StringRepresentation representation = null; - // String clusterName = getValue("clusterName"); - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); HelixAdmin admin = setupTool.getClusterManagementTool(); ZNRecord record = new ZNRecord(scopeProperty + " Config"); @@ -117,6 +119,18 @@ public class ConfigResource extends ServerResource { return representation; } + /** + * Get scoped configs + * <p> + * Usage: + * <p> + * <li>Get cluster-level configs: + * <code>curl http://{host:port}/clusters/{clusterName}/configs/cluster + * <li>Get instance-level configs: + * <code>curl http://{host:port}/clusters/{clusterName}/configs/participant/{instanceName} + * <li>Get resource-level configs: + * <code>curl http://{host:port}/clusters/{clusterName}/configs/resource/{resourceName} + */ @Override public Representation get() { StringRepresentation representation = null; @@ -143,15 +157,6 @@ public class ConfigResource extends ServerResource { } else { // path is "/clusters/{clusterName}/configs/cluster|participant|resource/ // {clusterName}|{participantName}|{resourceName}" - // ConfigScope scope; - // if (scopeProperty == ConfigScopeProperty.CLUSTER) - // { - // scope = new ConfigScopeBuilder().build(scopeProperty, clusterName); - // } - // else - // { - // scope = new ConfigScopeBuilder().build(scopeProperty, clusterName, scopeKey1); - // } representation = getConfigs(scopeProperty, clusterName, scopeKey1); } break; @@ -167,11 +172,6 @@ public class ConfigResource extends ServerResource { } else { // path is // "/clusters/{clusterName}/configs/partition/resourceName/partitionName" - // ConfigScope scope = - // new ConfigScopeBuilder().build(scopeProperty, - // clusterName, - // scopeKey1, - // scopeKey2); representation = getConfigs(scopeProperty, clusterName, scopeKey1, scopeKey2); } break; @@ -198,13 +198,13 @@ public class ConfigResource extends ServerResource { JsonParameters jsonParameters = new JsonParameters(entity); String command = jsonParameters.getCommand(); - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); if (command.equalsIgnoreCase(ClusterSetup.setConfig)) { jsonParameters.verifyCommand(ClusterSetup.setConfig); String propertiesStr = jsonParameters.getParameter(JsonParameters.CONFIGS); - // setupTool.setConfig(scopeStr, propertiesStr); setupTool.setConfig(type, scopeArgs, propertiesStr); } else if (command.equalsIgnoreCase(ClusterSetup.removeConfig)) { jsonParameters.verifyCommand(ClusterSetup.removeConfig); @@ -221,8 +221,31 @@ public class ConfigResource extends ServerResource { getResponse().setStatus(Status.SUCCESS_OK); } - -@Override + /** + * Set/remove scoped configs + * <p> + * Usage: + * <p> + * <li>Set cluster level configs: + * <code>curl -d 'jsonParameters={"command":"setConfig","configs":"{key1=value1,key2=value2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/cluster + * <li>Remove cluster level configs: + * <code>curl -d 'jsonParameters={"command":"removeConfig","configs":"{key1,key2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/cluster + * <li>Set instance level configs: + * <code>curl -d 'jsonParameters={"command":"setConfig","configs":"{key1=value1,key2=value2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/participant/{instanceName} + * <li>Remove instance level configs: + * <code>curl -d 'jsonParameters={"command":"removeConfig","configs":"{key1,key2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/participant/{instanceName} + * <li>Set resource level configs: + * <code>curl -d 'jsonParameters={"command":"setConfig","configs":"{key1=value1,key2=value2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/resource/{resourceName} + * <li>Remove resource level configs: + * <code>curl -d 'jsonParameters={"command":"removeConfig","configs":"{key1,key2}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/configs/resource/{resourceName} + */ + @Override public Representation post(Representation entity) { String clusterName = getValue("clusterName"); http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java index 675d0ec..090a518 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java @@ -27,11 +27,7 @@ import org.apache.helix.manager.zk.ZKHelixAdmin; import org.apache.helix.manager.zk.ZkClient; import org.apache.helix.model.ClusterConstraints.ConstraintType; import org.apache.helix.tools.ClusterSetup; -import org.apache.helix.webapp.RestAdminApplication; import org.apache.log4j.Logger; -import org.restlet.Context; -import org.restlet.Request; -import org.restlet.Response; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.representation.Representation; @@ -39,8 +35,14 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code>"/clusters/{clusterName}/constraints/{constraintType}" + * <p> + * <li>GET list all constraints + * <li>POST set constraints + * <li>DELETE remove constraints + */ public class ConstraintResource extends ServerResource { - private final static Logger LOG = Logger.getLogger(ConstraintResource.class); public ConstraintResource() { @@ -49,24 +51,26 @@ public class ConstraintResource extends ServerResource { setNegotiated(false); } - // TODO move to a util function - String getValue(String key) { - return (String) getRequest().getAttributes().get(key); - } - + /** + * List all constraints + * <p> + * Usage: <code>curl http://{host:port}/clusters/{clusterName}/constraints/MESSAGE_CONSTRAINT + */ @Override public Representation get() { StringRepresentation representation = null; - String clusterName = getValue("clusterName"); - String constraintTypeStr = getValue("constraintType").toUpperCase(); - String constraintId = getValue("constraintId"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); + String constraintTypeStr = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_TYPE); + String constraintId = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_ID); try { ConstraintType constraintType = ConstraintType.valueOf(constraintTypeStr); ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); - // ClusterSetup setupTool = new ClusterSetup(zkClient); - HelixAdmin admin = new ZKHelixAdmin(zkClient); // setupTool.getClusterManagementTool(); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); + HelixAdmin admin = new ZKHelixAdmin(zkClient); ZNRecord record = admin.getConstraints(clusterName, constraintType).getRecord(); if (constraintId == null) { @@ -96,21 +100,31 @@ public class ConstraintResource extends ServerResource { } catch (Exception e) { String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e); representation = new StringRepresentation(error, MediaType.APPLICATION_JSON); - LOG.error("", e); + LOG.error("Exception get constraints", e); } return representation; } + /** + * Set constraints + * <p> + * Usage: + * <code>curl -d 'jsonParameters={"constraintAttributes":"RESOURCE={resource},CONSTRAINT_VALUE={1}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{cluster}/constraints/MESSAGE_CONSTRAINT/{constraintId} + */ @Override public Representation post(Representation entity) { - String clusterName = getValue("clusterName"); - String constraintTypeStr = getValue("constraintType").toUpperCase(); - String constraintId = getValue("constraintId"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); + String constraintTypeStr = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_TYPE); + String constraintId = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_ID); try { ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); JsonParameters jsonParameters = new JsonParameters(entity); @@ -126,21 +140,29 @@ public class ConstraintResource extends ServerResource { return null; } + /** + * Remove constraints + * <p> + * Usage: + * <code>curl -X DELETE http://{host:port}/clusters/{cluster}/constraints/MESSAGE_CONSTRAINT/{constraintId} + */ @Override public Representation delete() { - String clusterName = getValue("clusterName"); - String constraintTypeStr = getValue("constraintType").toUpperCase(); - String constraintId = getValue("constraintId"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); + String constraintTypeStr = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_TYPE); + String constraintId = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CONSTRAINT_ID); try { ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); setupTool.removeConstraint(clusterName, constraintTypeStr, constraintId); - } catch (Exception e) { - LOG.error("Error in deleting ", e); + LOG.error("Error in delete constraint", e); getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e), MediaType.APPLICATION_JSON); getResponse().setStatus(Status.SUCCESS_OK); http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java index ea7be42..6288ab7 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java @@ -37,12 +37,9 @@ import org.apache.helix.manager.zk.ZkClient; import org.apache.helix.model.LiveInstance; import org.apache.helix.tools.ClusterSetup; import org.apache.helix.util.StatusUpdateUtil.Level; -import org.apache.helix.webapp.RestAdminApplication; +import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; -import org.restlet.Context; -import org.restlet.Request; -import org.restlet.Response; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.representation.Representation; @@ -50,10 +47,16 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code>"/clusters/{clusterName}/Controller" + * <p> + * <li>GET list Helix controller info + * <li>POST enable/disable Helix controller + */ public class ControllerResource extends ServerResource { + private final static Logger LOG = Logger.getLogger(ControllerResource.class); - public ControllerResource() - { + public ControllerResource() { getVariants().add(new Variant(MediaType.TEXT_PLAIN)); getVariants().add(new Variant(MediaType.APPLICATION_JSON)); setNegotiated(false); @@ -62,7 +65,8 @@ public class ControllerResource extends ServerResource { StringRepresentation getControllerRepresentation(String clusterName) throws JsonGenerationException, JsonMappingException, IOException { Builder keyBuilder = new PropertyKey.Builder(clusterName); - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ZKHelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<ZNRecord>(zkClient)); @@ -90,26 +94,40 @@ public class ControllerResource extends ServerResource { return representation; } + /** + * List Helix controller info + * <p> + * Usage: <code>curl http://{host:port}/clusters/{cluster}/Controller + */ @Override public Representation get() { StringRepresentation presentation = null; try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); presentation = getControllerRepresentation(clusterName); } catch (Exception e) { + LOG.error("Exception get controller info", e); String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e); presentation = new StringRepresentation(error, MediaType.APPLICATION_JSON); - e.printStackTrace(); } return presentation; } + /** + * Enable/disable Helix controller + * <p> + * Usage: + * <code>curl -d 'jsonParameters={"command":"enableCluster","enabled":"{true/false}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{cluster}/Controller + */ @Override public Representation post(Representation entity) { try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); JsonParameters jsonParameters = new JsonParameters(entity); @@ -135,7 +153,7 @@ public class ControllerResource extends ServerResource { MediaType.APPLICATION_JSON); getResponse().setStatus(Status.SUCCESS_OK); } - + return null; } } http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java index 49df073..0081922 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java @@ -30,7 +30,6 @@ import org.apache.helix.ZNRecord; import org.apache.helix.manager.zk.ZkClient; import org.apache.helix.model.IdealState; import org.apache.helix.tools.ClusterSetup; -import org.apache.helix.webapp.RestAdminApplication; import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; @@ -41,6 +40,13 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at + * <code>"/clusters/{clusterName}/resourceGroups/{resourceName}/idealState" + * <p> + * <li>GET get ideal state + * <li>POST set ideal state + */ public class IdealStateResource extends ServerResource { private final static Logger LOG = Logger.getLogger(IdealStateResource.class); @@ -50,12 +56,20 @@ public class IdealStateResource extends ServerResource { setNegotiated(false); } + /** + * Get ideal state + * <p> + * Usage: + * <code>curl http://{host:port}/clusters/{clusterName}/resourceGroups/{resourceName}/idealState + */ @Override public Representation get() { StringRepresentation presentation = null; try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); - String resourceName = (String) getRequest().getAttributes().get("resourceName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); + String resourceName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.RESOURCE_NAME); presentation = getIdealStateRepresentation(clusterName, resourceName); } @@ -71,7 +85,8 @@ public class IdealStateResource extends ServerResource { StringRepresentation getIdealStateRepresentation(String clusterName, String resourceName) throws JsonGenerationException, JsonMappingException, IOException { Builder keyBuilder = new PropertyKey.Builder(clusterName); - ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ZkClient zkClient = + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); String message = ClusterRepresentationUtil.getClusterPropertyAsString(zkClient, clusterName, @@ -83,13 +98,54 @@ public class IdealStateResource extends ServerResource { return representation; } + /** + * Set ideal state + * <p> + * Usage: + * <p> + * <li>Add ideal state: + * <code>curl -d @'{newIdealState.json}' -H 'Content-Type: application/json' + * http://{host:port}/clusters/{cluster}/resourceGroups/{resource}/idealState + * <pre> + * newIdealState: + * jsonParameters={"command":"addIdealState"}&newIdealState={ + * "id" : "{MyDB}", + * "simpleFields" : { + * "IDEAL_STATE_MODE" : "AUTO", + * "NUM_PARTITIONS" : "{8}", + * "REBALANCE_MODE" : "SEMI_AUTO", + * "REPLICAS" : "0", + * "STATE_MODEL_DEF_REF" : "MasterSlave", + * "STATE_MODEL_FACTORY_NAME" : "DEFAULT" + * }, + * "listFields" : { + * }, + * "mapFields" : { + * "{MyDB_0}" : { + * "{localhost_1001}" : "MASTER", + * "{localhost_1002}" : "SLAVE" + * } + * } + * } + * </pre> + * <li>Rebalance cluster: + * <code>curl -d 'jsonParameters={"command":"rebalance","replicas":"{3}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{cluster}/resourceGroups/{resource}/idealState + * <li>Expand resource: <code>n/a + * <li>Add resource property: + * <code>curl -d 'jsonParameters={"command":"addResourceProperty","{REBALANCE_TIMER_PERIOD}":"{500}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{cluster}/resourceGroups/{resource}/idealState + */ @Override public Representation post(Representation entity) { try { - String clusterName = (String) getRequest().getAttributes().get("clusterName"); - String resourceName = (String) getRequest().getAttributes().get("resourceName"); + String clusterName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.CLUSTER_NAME); + String resourceName = + ResourceUtil.getAttributeFromRequest(getRequest(), ResourceUtil.RequestKey.RESOURCE_NAME); + ZkClient zkClient = - (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT); + ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT); ClusterSetup setupTool = new ClusterSetup(zkClient); JsonParameters jsonParameters = new JsonParameters(entity); http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java index 3ff9a37..830e16b 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java @@ -46,6 +46,12 @@ import org.restlet.resource.ServerResource; import java.util.Map; +/** + * Class for server-side resource at <code>"/clusters/{clusterName}/jobQueues/{jobQueue}" + * <p> + * <li>GET list job queue info + * <li>POST start a new job in a job queue, or stop/resume/flush/delete a job queue + */ public class JobQueueResource extends ServerResource { private final static Logger LOG = Logger.getLogger(JobQueueResource.class); @@ -55,6 +61,11 @@ public class JobQueueResource extends ServerResource { setNegotiated(false); } + /** + * List job queue info + * <p> + * Usage: <code>curl http://{host:port}/clusters/{clusterName}/jobQueues/{jobQueue} + */ @Override public Representation get() { StringRepresentation presentation; @@ -105,6 +116,22 @@ public class JobQueueResource extends ServerResource { return representation; } + /** + * Start a new job in a job queue, or stop/resume/flush/delete a job queue + * <p> + * Usage: + * <p> + * <li>Start a new job in a job queue: + * <code>curl -d @'./{input.txt}' -H 'Content-Type: application/json' + * http://{host:port}/clusters/{clusterName}/jobQueues/{jobQueue} + * <p> + * input.txt: <code>jsonParameters={"command":"start"}&newJob={newJobConfig.yaml} + * <p> + * For newJobConfig.yaml, see {@link Workflow#parse(String)} + * <li>Stop/resume/flush/delete a job queue: + * <code>curl -d 'jsonParameters={"command":"{stop/resume/flush/delete}"}' + * -H "Content-Type: application/json" http://{host:port}/clusters/{clusterName}/jobQueues/{jobQueue} + */ @Override public Representation post(Representation entity) { String clusterName = @@ -123,7 +150,8 @@ public class JobQueueResource extends ServerResource { switch (cmd) { case start: { // Get the job queue and submit it - String yamlPayload = ResourceUtil.getYamlParameters(form, ResourceUtil.YamlParamKey.NEW_JOB); + String yamlPayload = + ResourceUtil.getYamlParameters(form, ResourceUtil.YamlParamKey.NEW_JOB); if (yamlPayload == null) { throw new HelixException("Yaml job config is required!"); } @@ -161,7 +189,6 @@ public class JobQueueResource extends ServerResource { } getResponse().setEntity(getHostedEntitiesRepresentation(clusterName, jobQueueName)); getResponse().setStatus(Status.SUCCESS_OK); - } catch (Exception e) { getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e), MediaType.APPLICATION_JSON); http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java index 24a4387..1a5cb17 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java @@ -47,6 +47,12 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +/** + * Class for server-side resource at <code>"/clusters/{clusterName}/jobQueues" + * <p> + * <li>GET list all job queues + * <li>POST add a new job queue + */ public class JobQueuesResource extends ServerResource { private final static Logger LOG = Logger.getLogger(JobQueuesResource.class); @@ -56,6 +62,11 @@ public class JobQueuesResource extends ServerResource { setNegotiated(false); } + /** + * List all job queues + * <p> + * Usage: <code>curl http://{host:port}/clusters/{clusterName}/jobQueues + */ @Override public Representation get() { StringRepresentation presentation = null; @@ -110,6 +121,15 @@ public class JobQueuesResource extends ServerResource { return representation; } + /** + * Add a new job queue + * <p> + * Usage: + * <code>curl -d @'{jobQueueConfig.yaml}' + * -H 'Content-Type: application/json' http://{host:port}/clusters/{clusterName}/jobQueues + * <p> + * For jobQueueConfig.yaml, see {@link Workflow#parse(String)} + */ @Override public Representation post(Representation entity) { try { http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java index a58e223..0193c4c 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java @@ -38,6 +38,11 @@ import org.restlet.representation.StringRepresentation; import org.restlet.representation.Variant; import org.restlet.resource.ServerResource; +/** + * Class for server-side resource at <code>"/clusters/{clusterName}/jobQueues/{jobQueue}/{job}" + * <p> + * <li>GET list job info + */ public class JobResource extends ServerResource { private final static Logger LOG = Logger.getLogger(JobResource.class); @@ -47,6 +52,11 @@ public class JobResource extends ServerResource { setNegotiated(false); } + /** + * List job info + * <p> + * Usage: <code>curl http://{host:port}/clusters/{clusterName}/jobQueues/{jobQueue}/{job} + */ @Override public Representation get() { StringRepresentation presentation; http://git-wip-us.apache.org/repos/asf/helix/blob/9a5dbeaa/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java ---------------------------------------------------------------------- diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java index 969bdf5..f066dfc 100644 --- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java +++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java @@ -33,7 +33,10 @@ public class ResourceUtil { public enum RequestKey { CLUSTER_NAME("clusterName"), JOB_QUEUE("jobQueue"), - JOB("job"); + JOB("job"), + CONSTRAINT_TYPE("constraintType"), + CONSTRAINT_ID("constraintId"), + RESOURCE_NAME("resourceName"); private final String _key;
