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 <17555551+jackie-ji...@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-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org