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

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


The following commit(s) were added to refs/heads/master by this push:
     new 47134888e RANGER-4937: Add a new GDS resource API for adding new 
resources to a new or existing DataShare and add it to the DataSet
47134888e is described below

commit 47134888e61f373769c7d40181101f43a1e30f83
Author: Ramesh Mani <[email protected]>
AuthorDate: Sun Oct 6 16:41:40 2024 -0700

    RANGER-4937: Add a new GDS resource API for adding new resources to a new 
or existing DataShare and add it to the DataSet
---
 .../main/java/org/apache/ranger/rest/GdsREST.java  | 155 +++++++++++++++++++++
 1 file changed, 155 insertions(+)

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 0b3d91001..525a5eca3 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
@@ -25,9 +25,12 @@ import 
org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
 import org.apache.ranger.biz.AssetMgr;
 import org.apache.ranger.biz.GdsDBStore;
 import org.apache.ranger.biz.RangerBizUtil;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.RESTErrorUtil;
 import org.apache.ranger.common.RangerSearchUtil;
 import org.apache.ranger.common.ServiceUtil;
+import org.apache.ranger.plugin.model.RangerGds;
 import org.apache.ranger.plugin.model.RangerGds.RangerDataset;
 import org.apache.ranger.plugin.model.RangerGds.RangerDatasetInProject;
 import org.apache.ranger.plugin.model.RangerGds.RangerDataShareInDataset;
@@ -39,8 +42,11 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerGds.DatasetSummary;
 import org.apache.ranger.plugin.model.RangerGds.DataShareSummary;
 import org.apache.ranger.plugin.model.RangerGds.DataShareInDatasetSummary;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
 import org.apache.ranger.plugin.store.PList;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServiceGdsInfo;
 import org.apache.ranger.security.context.RangerAPIList;
@@ -65,7 +71,10 @@ import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
 import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 @Path("gds")
 @Component
@@ -114,6 +123,9 @@ public class GdsREST {
     @Autowired
     ServiceUtil serviceUtil;
 
+    @Autowired
+    ServiceDBStore serviceDBStore;
+
     @Autowired
     AssetMgr assetMgr;
 
@@ -150,6 +162,44 @@ public class GdsREST {
         return ret;
     }
 
+    @POST
+    @Path("/dataset/{id}/resources/{serviceName}")
+    @Consumes({ "application/json" })
+    @Produces({ "application/json" })
+    @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + 
RangerAPIList.ADD_SHARED_RESOURCES + "\")")
+    public List<RangerSharedResource> addDatasetResources(@PathParam("id") 
Long datasetId,
+                                                          
@PathParam("serviceName") String serviceName,
+                                                          
@QueryParam("zoneName") @DefaultValue("") String zoneName,
+                                                          
List<RangerSharedResource> resources) {
+        LOG.debug("==> GdsREST.addDatasetResources(datasetId={} serviceName={} 
zoneNam={} resources={})", datasetId, serviceName, zoneName, resources);
+
+        List<RangerSharedResource> ret  = new ArrayList<>();
+        RangerPerfTracer           perf = null;
+
+        try {
+            Long serviceId   = validateAndGetServiceId(serviceName);
+            Long zoneId      = validateAndGetZoneId(zoneName);
+            Long dataShareId = getOrCreateDataShare(datasetId, serviceId, 
zoneId, serviceName);
+            // Add resources to DataShare
+            for (RangerSharedResource resource : resources) {
+                resource.setDataShareId(dataShareId);
+                RangerSharedResource rangerSharedResource = 
addSharedResource(resource);
+                ret.add(rangerSharedResource);
+            }
+        } catch(WebApplicationException excp) {
+            throw excp;
+        } catch(Throwable excp) {
+            LOG.error("GdsREST.addDatasetResources(datasetId={} serviceName={} 
zoneName={} resources={}) failed!", datasetId, serviceName, zoneName, 
resources, excp);
+            throw restErrorUtil.createRESTException(excp.getMessage());
+        } finally {
+            RangerPerfTracer.log(perf);
+        }
+
+        LOG.debug("<== GdsREST.addDatasetResources(RangerSharedResources={})", 
ret);
+
+        return ret;
+    }
+
     @POST
     @Path("/dataset/{id}/datashare")
     @Consumes({ "application/json" })
@@ -1715,4 +1765,109 @@ public class GdsREST {
 
         return ret;
     }
+
+    private Long getOrCreateDataShare(Long datasetId, Long serviceId, Long 
zoneId, String serviceName) throws Exception {
+        LOG.debug("==> GdsREST.getOrCreateDataShare(dataSetId={} serviceId={} 
zoneId={} seviceName={})", datasetId);
+
+        Long ret;
+        RangerDataShare rangerDataShare;
+        RangerDataset   rangerDataset = gdsStore.getDataset(datasetId);
+        String          dataShareName = "__dataset_" + datasetId + 
"__service_" + serviceId + "__zone_" + zoneId;
+
+        SearchFilter filter = new SearchFilter();
+        filter.setParam(SearchFilter.DATA_SHARE_NAME, dataShareName);
+        PList<RangerDataShare> dataSharePList = 
gdsStore.searchDataShares(filter);
+        List<RangerDataShare> dataShareList = dataSharePList.getList();
+
+        if (CollectionUtils.isNotEmpty(dataShareList)) {
+            List<RangerDataShare> rangerDataShares = dataSharePList.getList();
+            rangerDataShare = rangerDataShares.get(0);
+            ret = rangerDataShare.getId();
+        } else {
+            //Create a DataShare
+            RangerDataShare dataShare = new RangerDataShare();
+            dataShare.setName(dataShareName);
+            dataShare.setDescription(dataShareName);
+            dataShare.setTermsOfUse(rangerDataset.getTermsOfUse());
+            dataShare.setService(serviceName);
+            Set<String> accessTypes = new 
HashSet<>(CollectionUtils.EMPTY_COLLECTION);
+            dataShare.setDefaultAccessTypes(accessTypes);
+            rangerDataShare = gdsStore.createDataShare(dataShare);
+
+            //Add DataShare to DataSet
+            List<RangerDataShareInDataset> rangerDataShareInDatasets = new 
ArrayList<>();
+            RangerDataShareInDataset rangerDataShareInDataset = new 
RangerDataShareInDataset();
+            rangerDataShareInDataset.setDataShareId(rangerDataShare.getId());
+            rangerDataShareInDataset.setDatasetId(rangerDataset.getId());
+            
rangerDataShareInDataset.setStatus(RangerGds.GdsShareStatus.ACTIVE);
+            rangerDataShareInDatasets.add(rangerDataShareInDataset);
+            addDataSharesInDataset(rangerDataset.getId(), 
rangerDataShareInDatasets);
+            ret = rangerDataShare.getId();
+        }
+
+        LOG.debug("<== GdsREST.getOrCreateDataShare(RangerDataShare={})", ret);
+
+        return ret;
+    }
+
+    private Long validateAndGetServiceId(String serviceName){
+        Long ret;
+        if (serviceName == null || serviceName.isEmpty()) {
+            LOG.error("ServiceName not provided");
+            throw restErrorUtil.createRESTException("ServiceName not 
provided.",
+                    MessageEnums.INVALID_INPUT_DATA);
+        }
+
+        RangerService service;
+
+        try {
+            service = serviceDBStore.getServiceByName(serviceName);
+            ret = service.getId();
+        } catch (Exception e) {
+            LOG.error("Requested Service not found. serviceName=" + 
serviceName);
+            throw restErrorUtil.createRESTException("Service:" + serviceName + 
" not found",
+                    MessageEnums.DATA_NOT_FOUND);
+        }
+
+        if(service == null){
+            LOG.error("Requested Service not found. serviceName=" + 
serviceName);
+            throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, 
RangerServiceNotFoundException.buildExceptionMsg(serviceName),
+                    false);
+        }
+
+        if(!service.getIsEnabled()){
+            LOG.error("Requested Service is disabled. serviceName=" + 
serviceName);
+            throw restErrorUtil.createRESTException("Unauthorized access.",
+                    MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
+        }
+
+        return ret;
+    }
+
+    private Long validateAndGetZoneId(String zoneName){
+        Long ret = RangerSecurityZone.RANGER_UNZONED_SECURITY_ZONE_ID;
+
+        if (zoneName == null || zoneName.isEmpty()) {
+            return ret;
+        }
+
+        RangerSecurityZone rangerSecurityZone = null;
+
+        try {
+            rangerSecurityZone = serviceDBStore.getSecurityZone(zoneName);
+            ret = rangerSecurityZone.getId();
+        } catch (Exception e) {
+            LOG.error("Requested Zone not found. ZoneName=" + zoneName);
+            throw restErrorUtil.createRESTException("Zone:" + zoneName + " not 
found",
+                    MessageEnums.DATA_NOT_FOUND);
+        }
+
+        if(rangerSecurityZone == null){
+            LOG.error("Requested Zone not found. ZoneName=" + zoneName);
+            throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, 
RangerServiceNotFoundException.buildExceptionMsg(zoneName),
+                    false);
+        }
+
+        return ret;
+    }
 }

Reply via email to