You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ja...@apache.org on 2023/07/14 21:38:00 UTC

[pinot] branch master updated: Use PUT request to enable/disable table/instance (#11109)

This is an automated email from the ASF dual-hosted git repository.

jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 3d60d556c8 Use PUT request to enable/disable table/instance (#11109)
3d60d556c8 is described below

commit 3d60d556c82a6b3282e740af15b30eb67267b36f
Author: Xiaotian (Jackie) Jiang <17...@users.noreply.github.com>
AuthorDate: Fri Jul 14 14:37:54 2023 -0700

    Use PUT request to enable/disable table/instance (#11109)
---
 .../resources/PinotInstanceRestletResource.java    | 44 +++++++++++++++++++-
 .../api/resources/PinotTableRestletResource.java   | 48 ++++++++++++++++++++--
 .../helix/ControllerInstanceToggleTest.java        |  3 +-
 3 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotInstanceRestletResource.java b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotInstanceRestletResource.java
index 5752599d0a..dacd4a5e51 100644
--- a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotInstanceRestletResource.java
+++ b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotInstanceRestletResource.java
@@ -216,6 +216,48 @@ public class PinotInstanceRestletResource {
     }
   }
 
+  @PUT
+  @Path("/instances/{instanceName}/state")
+  @Authenticate(AccessType.UPDATE)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Enable/disable an instance", notes = "Enable/disable an instance")
+  @ApiResponses(value = {
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Instance not found"),
+      @ApiResponse(code = 500, message = "Internal error")
+  })
+  public SuccessResponse toggleInstanceState(
+      @ApiParam(value = "Instance name", required = true, example = "Server_a.b.com_20000 | Broker_my.broker.com_30000")
+      @PathParam("instanceName") String instanceName,
+      @ApiParam(value = "enable|disable", required = true) @QueryParam("state") String state) {
+    if (!_pinotHelixResourceManager.instanceExists(instanceName)) {
+      throw new ControllerApplicationException(LOGGER, "Instance '" + instanceName + "' does not exist",
+          Response.Status.NOT_FOUND);
+    }
+
+    if (StateType.ENABLE.name().equalsIgnoreCase(state)) {
+      PinotResourceManagerResponse response = _pinotHelixResourceManager.enableInstance(instanceName);
+      if (!response.isSuccessful()) {
+        throw new ControllerApplicationException(LOGGER,
+            "Failed to enable instance '" + instanceName + "': " + response.getMessage(),
+            Response.Status.INTERNAL_SERVER_ERROR);
+      }
+    } else if (StateType.DISABLE.name().equalsIgnoreCase(state)) {
+      PinotResourceManagerResponse response = _pinotHelixResourceManager.disableInstance(instanceName);
+      if (!response.isSuccessful()) {
+        throw new ControllerApplicationException(LOGGER,
+            "Failed to disable instance '" + instanceName + "': " + response.getMessage(),
+            Response.Status.INTERNAL_SERVER_ERROR);
+      }
+    } else {
+      throw new ControllerApplicationException(LOGGER, "Unknown state '" + state + "'", Response.Status.BAD_REQUEST);
+    }
+    return new SuccessResponse("Request to " + state + " instance '" + instanceName + "' is successful");
+  }
+
+  @Deprecated
   @POST
   @Path("/instances/{instanceName}/state")
   @Authenticate(AccessType.UPDATE)
@@ -229,7 +271,7 @@ public class PinotInstanceRestletResource {
       @ApiResponse(code = 409, message = "Instance cannot be dropped"),
       @ApiResponse(code = 500, message = "Internal error")
   })
-  public SuccessResponse toggleInstanceState(
+  public SuccessResponse toggleInstanceStateDeprecated(
       @ApiParam(value = "Instance name", required = true, example = "Server_a.b.com_20000 | Broker_my.broker.com_30000")
       @PathParam("instanceName") String instanceName, String state) {
     if (!_pinotHelixResourceManager.instanceExists(instanceName)) {
diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
index 36735a96c8..a5f7e26901 100644
--- a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
+++ b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
@@ -28,6 +28,8 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiKeyAuthDefinition;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
 import io.swagger.annotations.Authorization;
 import io.swagger.annotations.SecurityDefinition;
 import io.swagger.annotations.SwaggerDefinition;
@@ -90,6 +92,7 @@ import org.apache.pinot.controller.api.exception.ControllerApplicationException;
 import org.apache.pinot.controller.api.exception.InvalidTableConfigException;
 import org.apache.pinot.controller.api.exception.TableAlreadyExistsException;
 import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.controller.helix.core.PinotResourceManagerResponse;
 import org.apache.pinot.controller.helix.core.minion.PinotHelixTaskResourceManager;
 import org.apache.pinot.controller.helix.core.rebalance.RebalanceResult;
 import org.apache.pinot.controller.helix.core.rebalance.TableRebalanceProgressStats;
@@ -363,9 +366,7 @@ public class PinotTableRestletResource {
   @GET
   @Produces(MediaType.APPLICATION_JSON)
   @Path("/tables/{tableName}")
-  @ApiOperation(value = "Get/Enable/Disable/Drop a table",
-      notes = "Get/Enable/Disable/Drop a table. If table name is the only parameter specified "
-          + ", the tableconfig will be printed")
+  @ApiOperation(value = "Lists the table configs")
   public String alterTableStateOrListTableConfig(
       @ApiParam(value = "Name of the table", required = true) @PathParam("tableName") String tableName,
       @ApiParam(value = "enable|disable|drop") @QueryParam("state") String stateStr,
@@ -376,6 +377,8 @@ public class PinotTableRestletResource {
         return listTableConfigs(tableName, tableTypeStr);
       }
 
+      // TODO: DO NOT allow toggling state with GET request
+
       StateType stateType = Constants.validateState(stateStr);
       TableType tableType = Constants.validateTableType(tableTypeStr);
 
@@ -717,6 +720,45 @@ public class PinotTableRestletResource {
     }
   }
 
+  @PUT
+  @Path("/tables/{tableName}/state")
+  @Authenticate(AccessType.UPDATE)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Enable/disable a table", notes = "Enable/disable a table")
+  @ApiResponses(value = {
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Table not found"),
+      @ApiResponse(code = 500, message = "Internal error")
+  })
+  public SuccessResponse toggleTableState(
+      @ApiParam(value = "Table name", required = true) @PathParam("tableName") String tableName,
+      @ApiParam(value = "realtime|offline", required = true) @QueryParam("type") String tableTypeStr,
+      @ApiParam(value = "enable|disable", required = true) @QueryParam("state") String state) {
+    String tableNameWithType = constructTableNameWithType(tableName, tableTypeStr);
+    StateType stateType;
+    if (StateType.ENABLE.name().equalsIgnoreCase(state)) {
+      stateType = StateType.ENABLE;
+    } else if (StateType.DISABLE.name().equalsIgnoreCase(state)) {
+      stateType = StateType.DISABLE;
+    } else {
+      throw new ControllerApplicationException(LOGGER, "Unknown state '" + state + "'", Response.Status.BAD_REQUEST);
+    }
+    if (!_pinotHelixResourceManager.hasTable(tableNameWithType)) {
+      throw new ControllerApplicationException(LOGGER, "Table '" + tableName + "' does not exist",
+          Response.Status.NOT_FOUND);
+    }
+    PinotResourceManagerResponse response = _pinotHelixResourceManager.toggleTableState(tableNameWithType, stateType);
+    if (response.isSuccessful()) {
+      return new SuccessResponse("Request to " + state + " table '" + tableNameWithType + "' is successful");
+    } else {
+      throw new ControllerApplicationException(LOGGER,
+          "Failed to " + state + " table '" + tableNameWithType + "': " + response.getMessage(),
+          Response.Status.INTERNAL_SERVER_ERROR);
+    }
+  }
+
   @GET
   @Produces(MediaType.APPLICATION_JSON)
   @Authenticate(AccessType.UPDATE)
diff --git a/pinot-controller/src/test/java/org/apache/pinot/controller/helix/ControllerInstanceToggleTest.java b/pinot-controller/src/test/java/org/apache/pinot/controller/helix/ControllerInstanceToggleTest.java
index 9528e2dbbf..6fe3e56576 100644
--- a/pinot-controller/src/test/java/org/apache/pinot/controller/helix/ControllerInstanceToggleTest.java
+++ b/pinot-controller/src/test/java/org/apache/pinot/controller/helix/ControllerInstanceToggleTest.java
@@ -116,7 +116,8 @@ public class ControllerInstanceToggleTest extends ControllerTest {
     // It may take time for an instance to toggle the state.
     TestUtils.waitForCondition(aVoid -> {
       try {
-        sendPostRequest(DEFAULT_INSTANCE.getControllerRequestURLBuilder().forInstanceState(instanceName), state);
+        sendPutRequest(
+            DEFAULT_INSTANCE.getControllerRequestURLBuilder().forInstanceState(instanceName) + "?state=" + state);
       } catch (IOException ioe) {
         // receive non-200 status code
         return false;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org