This is an automated email from the ASF dual-hosted git repository. madhan pushed a commit to branch RANGER-3923 in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/RANGER-3923 by this push: new 2406a5742 RANGER-4415: new API to add multiple datashares in a dataset 2406a5742 is described below commit 2406a5742c74abc3c6d9c6e462dc8f7fdb64a7e8 Author: Subhrat Chaudhary <such...@yahoo.com> AuthorDate: Sun Oct 15 12:33:32 2023 -0700 RANGER-4415: new API to add multiple datashares in a dataset Signed-off-by: Madhan Neethiraj <mad...@apache.org> --- .../java/org/apache/ranger/biz/GdsDBStore.java | 76 +++++++++++++++------- .../main/java/org/apache/ranger/rest/GdsREST.java | 54 +++++++++++++-- 2 files changed, 103 insertions(+), 27 deletions(-) diff --git a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java index 4d2a9cc8f..10986823d 100755 --- a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java @@ -1008,38 +1008,29 @@ public class GdsDBStore extends AbstractGdsStore { return ret; } + public List<RangerDataShareInDataset> addDataSharesInDataset(List<RangerDataShareInDataset> dataSharesInDataset) throws Exception { + LOG.debug("==> addDataSharesInDataset({})", dataSharesInDataset); - @Override - public RangerDataShareInDataset addDataShareInDataset(RangerDataShareInDataset dataShareInDataset) throws Exception { - LOG.debug("==> addDataShareInDataset({})", dataShareInDataset); + List<RangerDataShareInDataset> ret = new ArrayList<>(); - XXGdsDataShareInDatasetDao datasetDao = daoMgr.getXXGdsDataShareInDataset(); - XXGdsDataShareInDataset existing = datasetDao.findByDataShareIdAndDatasetId(dataShareInDataset.getDataShareId(), dataShareInDataset.getDatasetId()); + validate(dataSharesInDataset); - if (existing != null) { - throw new Exception("data share '" + dataShareInDataset.getDataShareId() + "' already shared with dataset " + dataShareInDataset.getDatasetId() + " - id=" + existing.getId()); + for (RangerDataShareInDataset dataShareInDataset : dataSharesInDataset) { + ret.add(createDataShareInDataset(dataShareInDataset)); } - validator.validateCreate(dataShareInDataset); + LOG.debug("<== addDataSharesInDataset({}): ret={}", dataSharesInDataset, ret); - switch (dataShareInDataset.getStatus()) { - case GRANTED: - case DENIED: - case ACTIVE: - dataShareInDataset.setApprover(bizUtil.getCurrentUserLoginId()); - break; - default: - dataShareInDataset.setApprover(null); - break; - } + return ret; + } - if (StringUtils.isBlank(dataShareInDataset.getGuid())) { - dataShareInDataset.setGuid(guidUtil.genGUID()); - } + @Override + public RangerDataShareInDataset addDataShareInDataset(RangerDataShareInDataset dataShareInDataset) throws Exception { + LOG.debug("==> addDataShareInDataset({})", dataShareInDataset); - RangerDataShareInDataset ret = dataShareInDatasetService.create(dataShareInDataset); + validate(Collections.singletonList(dataShareInDataset)); - dataShareInDatasetService.onObjectChange(ret, null, RangerServiceService.OPERATION_CREATE_CONTEXT); + RangerDataShareInDataset ret = createDataShareInDataset(dataShareInDataset); LOG.debug("<== addDataShareInDataset({}): ret={}", dataShareInDataset, ret); @@ -1713,4 +1704,43 @@ public class GdsDBStore extends AbstractGdsStore { private boolean hasResource(List<String> resources, String resourceValue) { return resources.stream().filter(Objects::nonNull).anyMatch(resource -> resource.contains(resourceValue)); } + + private void validate(List<RangerDataShareInDataset> dataSharesInDataset) throws Exception { + XXGdsDataShareInDatasetDao dshInDsDao = daoMgr.getXXGdsDataShareInDataset(); + + if(CollectionUtils.isNotEmpty(dataSharesInDataset)) { + for(RangerDataShareInDataset dataShareInDataset : dataSharesInDataset) { + XXGdsDataShareInDataset existing = dshInDsDao.findByDataShareIdAndDatasetId(dataShareInDataset.getDataShareId(), dataShareInDataset.getDatasetId()); + + if (existing != null) { + throw new Exception("data share id='" + dataShareInDataset.getDataShareId() + "' already shared with dataset id='" + dataShareInDataset.getDatasetId() + "': dataShareInDatasetId=" + existing.getId()); + } + + validator.validateCreate(dataShareInDataset); + } + } + } + + private RangerDataShareInDataset createDataShareInDataset(RangerDataShareInDataset dataShareInDataset) { + switch (dataShareInDataset.getStatus()) { + case GRANTED: + case DENIED: + case ACTIVE: + dataShareInDataset.setApprover(bizUtil.getCurrentUserLoginId()); + break; + default: + dataShareInDataset.setApprover(null); + break; + } + + if (StringUtils.isBlank(dataShareInDataset.getGuid())) { + dataShareInDataset.setGuid(guidUtil.genGUID()); + } + + RangerDataShareInDataset ret = dataShareInDatasetService.create(dataShareInDataset); + + dataShareInDatasetService.onObjectChange(ret, null, RangerServiceService.OPERATION_CREATE_CONTEXT); + + return ret; + } } diff --git a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java index 18e4cc451..4c0a106ad 100755 --- a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java @@ -19,6 +19,7 @@ package org.apache.ranger.rest; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.ranger.biz.GdsDBStore; import org.apache.ranger.common.RESTErrorUtil; @@ -53,6 +54,7 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.ws.rs.*; import javax.ws.rs.core.Context; import java.util.List; @@ -125,6 +127,50 @@ public class GdsREST { return ret; } + @POST + @Path("/dataset/{id}/datashare") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.ADD_DATASHARE_IN_DATASET + "\")") + public List<RangerDataShareInDataset> addDataSharesInDataset(@PathParam("id") Long datasetId, List<RangerDataShareInDataset> dataSharesInDataset) { + LOG.debug("==> GdsREST.addDataSharesInDataset({}, {})", datasetId, dataSharesInDataset); + + List<RangerDataShareInDataset> ret; + RangerPerfTracer perf = null; + + try { + if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) { + perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "GdsREST.addDataSharesInDataset(" + datasetId + ")"); + } + + if (CollectionUtils.isNotEmpty(dataSharesInDataset)) { + for (RangerDataShareInDataset dshInDs : dataSharesInDataset) { + if (dshInDs == null || (dshInDs.getDatasetId() == null)) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, "missing datasetID", false); + } else if (!dshInDs.getDatasetId().equals(datasetId)) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, "incorrect datasetId=" + datasetId, false); + } + } + } else { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, "empty dataShareInDataset list", false); + } + + ret = gdsStore.addDataSharesInDataset(dataSharesInDataset); + } catch(WebApplicationException excp) { + throw excp; + } catch(Throwable excp) { + LOG.error("addDataShareInDataset({}) failed", datasetId, excp); + + throw restErrorUtil.createRESTException(excp.getMessage()); + } finally { + RangerPerfTracer.log(perf); + } + + LOG.debug("<== GdsREST.addDataSharesInDataset({}, {}): ret={}", datasetId, dataSharesInDataset, ret); + + return ret; + } + @PUT @Path("/dataset/{id}") @Consumes({ "application/json" }) @@ -206,7 +252,7 @@ public class GdsREST { ret = gdsStore.getDataset(datasetId); if (ret == null) { - throw new Exception("no dataset with id=" + datasetId); + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "no dataset with id=" + datasetId, false); } } catch(WebApplicationException excp) { throw excp; @@ -568,7 +614,7 @@ public class GdsREST { ret = gdsStore.getProject(projectId); if (ret == null) { - throw new Exception("no project with id=" + projectId); + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "no project with id=" + projectId, false); } } catch(WebApplicationException excp) { throw excp; @@ -895,7 +941,7 @@ public class GdsREST { ret = gdsStore.getDataShare(dataShareId); if (ret == null) { - throw new Exception("no resourceset with id=" + dataShareId); + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "no dataShare with id=" + dataShareId, false); } } catch(WebApplicationException excp) { throw excp; @@ -1082,7 +1128,7 @@ public class GdsREST { ret = gdsStore.getSharedResource(resourceId); if (ret == null) { - throw new Exception("no shared-resource with id=" + resourceId); + throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "no shared-resource with id=" + resourceId, false); } } catch(WebApplicationException excp) { throw excp;