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 2249be357b Rest Endpoint to Create ZNode (#12497) 2249be357b is described below commit 2249be357b89a27b1fb74879b4235393dd4e53d0 Author: Prashant Pandey <84911643+suddend...@users.noreply.github.com> AuthorDate: Fri Mar 1 00:12:53 2024 +0530 Rest Endpoint to Create ZNode (#12497) --- .../api/resources/ZookeeperResource.java | 62 ++++++++++++++++++++++ .../helix/core/PinotHelixResourceManager.java | 4 ++ .../utils/builder/ControllerRequestURLBuilder.java | 8 +++ 3 files changed, 74 insertions(+) diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/ZookeeperResource.java b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/ZookeeperResource.java index f6f1126ec1..377424125d 100644 --- a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/ZookeeperResource.java +++ b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/ZookeeperResource.java @@ -44,6 +44,7 @@ import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -52,6 +53,7 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.lang.StringUtils; +import org.apache.helix.AccessOption; import org.apache.helix.zookeeper.datamodel.ZNRecord; import org.apache.helix.zookeeper.introspect.CodehausJacksonIntrospector; import org.apache.pinot.controller.api.access.AccessType; @@ -256,6 +258,66 @@ public class ZookeeperResource { } } + @POST + @Path("/zk/create") + @Authorize(targetType = TargetType.CLUSTER, action = Actions.Cluster.UPDATE_ZNODE) + @Authenticate(AccessType.CREATE) + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create a node at a given path") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Success"), @ApiResponse(code = 204, message = "No Content"), + @ApiResponse(code = 400, message = "Bad Request"), @ApiResponse(code = 500, message = "Internal server error") + }) + public SuccessResponse createNode( + @ApiParam(value = "Zookeeper Path, must start with /", required = true) @QueryParam("path") String path, + @ApiParam(value = "TTL of the node. TTL are only honoured for persistent znodes (access option = 0x40 or 0x80)," + + " in which case TTL should be > 0. If access option is not 0x40 or 0x80, it will be ignored, and we can " + + "set it to any value, or just ignore it", defaultValue = "-1") @QueryParam("ttl") @DefaultValue("-1") + int ttl, @ApiParam(value = "accessOption", defaultValue = "1") @QueryParam("accessOption") @DefaultValue("1") + int accessOption, String payload) { + + path = validateAndNormalizeZKPath(path, false); + + //validate ttl range + if ((accessOption == AccessOption.PERSISTENT_WITH_TTL + || accessOption == AccessOption.PERSISTENT_SEQUENTIAL_WITH_TTL) && ttl <= 0) { + throw new ControllerApplicationException(LOGGER, "TTL for persistent nodes should be > 0", + Response.Status.BAD_REQUEST); + } + + if (StringUtils.isEmpty(payload)) { + throw new ControllerApplicationException(LOGGER, "Must provide payload", Response.Status.BAD_REQUEST); + } + ZNRecord znRecord; + try { + znRecord = MAPPER.readValue(payload, ZNRecord.class); + } catch (Exception e) { + throw new ControllerApplicationException(LOGGER, "Failed to deserialize the data", Response.Status.BAD_REQUEST, + e); + } + + boolean result; + try { + result = _pinotHelixResourceManager.createZKNode(path, znRecord, accessOption, ttl); + } catch (Exception e) { + throw new ControllerApplicationException(LOGGER, "Failed to create znode at path: " + path, + Response.Status.INTERNAL_SERVER_ERROR, e); + } + if (result) { + return new SuccessResponse("Successfully created node at path: " + path); + } else { + //check if node already exists + if (_pinotHelixResourceManager.getZKStat(path) != null) { + throw new ControllerApplicationException(LOGGER, "ZNode already exists at path: " + path, + Response.Status.BAD_REQUEST); + } else { + throw new ControllerApplicationException(LOGGER, "Failed to create znode at path: " + path, + Response.Status.INTERNAL_SERVER_ERROR); + } + } + } + @GET @Path("/zk/ls") @Authorize(targetType = TargetType.CLUSTER, action = Actions.Cluster.GET_ZNODE) diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java index 5e19ea9cf6..ab94f959b3 100644 --- a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java +++ b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java @@ -1712,6 +1712,10 @@ public class PinotHelixResourceManager { return _helixDataAccessor.getBaseDataAccessor().set(path, record, expectedVersion, accessOption); } + public boolean createZKNode(String path, ZNRecord record, int accessOption, long ttl) { + return _helixDataAccessor.getBaseDataAccessor().create(path, record, accessOption, ttl); + } + public boolean deleteZKPath(String path) { return _helixDataAccessor.getBaseDataAccessor().remove(path, -1); } diff --git a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/builder/ControllerRequestURLBuilder.java b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/builder/ControllerRequestURLBuilder.java index d4f255b778..66972561f9 100644 --- a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/builder/ControllerRequestURLBuilder.java +++ b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/builder/ControllerRequestURLBuilder.java @@ -525,6 +525,14 @@ public class ControllerRequestURLBuilder { return StringUtil.join("/", _baseUrl, "zk/putChildren", "?path=" + path); } + public String forZKCreate() { + return StringUtil.join("/", _baseUrl, "zk/create"); + } + + public String forZkDelete() { + return StringUtil.join("/", _baseUrl, "zk/delete"); + } + public String forZkGet(String path) { return StringUtil.join("/", _baseUrl, "zk/get", "?path=" + path); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org