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

dhavalshah9131 pushed a commit to branch RANGER-5199
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit f8f0721684d5091d7a04d12bd4d30d605ae8b423
Author: Radhika Kundam <radhika.kun...@gmail.com>
AuthorDate: Fri May 9 19:28:03 2025 -0700

    RANGER-5170: enhanced GDS admin audits to record the changes on impacted 
objects as well
    
    Signed-off-by: Madhan Neethiraj <mad...@apache.org>
---
 .../main/java/org/apache/ranger/biz/AssetMgr.java  | 133 ++++++++++++++++--
 .../java/org/apache/ranger/db/XXGdsDatasetDao.java |  17 +++
 .../apache/ranger/db/XXGdsDatasetPolicyMapDao.java |  16 +++
 .../java/org/apache/ranger/db/XXGdsProjectDao.java |  29 ++++
 .../apache/ranger/db/XXGdsProjectPolicyMapDao.java |  16 +++
 .../java/org/apache/ranger/rest/AssetREST.java     |  45 ++++--
 .../ranger/service/RangerAuditedModelService.java  | 152 +++++++++++++++++++--
 .../main/resources/META-INF/jpa_named_queries.xml  |  32 +++++
 .../java/org/apache/ranger/rest/TestAssetREST.java |  37 +++++
 9 files changed, 447 insertions(+), 30 deletions(-)

diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java 
b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
index ec39448f3..919e2d656 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
@@ -67,6 +67,7 @@
 import org.apache.ranger.view.VXTrxLogV2;
 import org.apache.ranger.view.VXTrxLogV2.AttributeChangeInfo;
 import org.apache.ranger.view.VXTrxLogV2.ObjectChangeInfo;
+import org.apache.ranger.view.VXTrxLogV2List;
 import org.apache.ranger.view.VXUgsyncAuditInfoList;
 import org.apache.ranger.view.VXUser;
 import org.slf4j.Logger;
@@ -84,6 +85,7 @@
 
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -606,6 +608,46 @@ public void createPluginInfo(String serviceName, String 
pluginId, HttpServletReq
     }
 
     public VXTrxLogList getReportLogs(SearchCriteria searchCriteria) {
+        VXTrxLogList      ret;
+        PList<VXTrxLogV2> vXTrxLogsV2 = getVXTrxLogsV2(searchCriteria);
+        List<VXTrxLog>    vxTrxLogs   = 
vXTrxLogsV2.getList().stream().map(VXTrxLogV2::toVXTrxLog).collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(vxTrxLogs)) {
+            ret = new VXTrxLogList(Collections.emptyList());
+        } else {
+            ret = new VXTrxLogList(validateXXTrxLogList(vxTrxLogs));
+
+            ret.setStartIndex(vXTrxLogsV2.getStartIndex());
+            ret.setPageSize(vXTrxLogsV2.getPageSize());
+            ret.setTotalCount(vXTrxLogsV2.getTotalCount());
+            ret.setResultSize(vXTrxLogsV2.getResultSize());
+            ret.setSortBy(vXTrxLogsV2.getSortBy());
+            ret.setSortType(vXTrxLogsV2.getSortType());
+        }
+
+        return ret;
+    }
+
+    public VXTrxLogV2List getReportLogsV2(SearchCriteria searchCriteria) {
+        VXTrxLogV2List    ret;
+        PList<VXTrxLogV2> vXTrxLogsV2 = getVXTrxLogsV2(searchCriteria);
+
+        if (vXTrxLogsV2 == null || 
CollectionUtils.isEmpty(vXTrxLogsV2.getList())) {
+            ret = new VXTrxLogV2List(Collections.emptyList());
+        } else {
+            ret = new 
VXTrxLogV2List(validateXXTrxLogV2List(vXTrxLogsV2.getList()));
+
+            ret.setStartIndex(vXTrxLogsV2.getStartIndex());
+            ret.setPageSize(vXTrxLogsV2.getPageSize());
+            ret.setTotalCount(vXTrxLogsV2.getTotalCount());
+            ret.setResultSize(vXTrxLogsV2.getResultSize());
+            ret.setSortBy(vXTrxLogsV2.getSortBy());
+            ret.setSortType(vXTrxLogsV2.getSortType());
+        }
+        return ret;
+    }
+
+    public PList<VXTrxLogV2> getVXTrxLogsV2(SearchCriteria searchCriteria) {
         if (xaBizUtil.isAdmin() || xaBizUtil.isKeyAdmin() || 
xaBizUtil.isAuditAdmin() || xaBizUtil.isAuditKeyAdmin()) {
             if (searchCriteria == null) {
                 searchCriteria = new SearchCriteria();
@@ -646,18 +688,7 @@ public VXTrxLogList getReportLogs(SearchCriteria 
searchCriteria) {
 
             searchCriteria.setGetCount(true);
 
-            PList<VXTrxLogV2> vXTrxLogsV2 = 
xTrxLogService.searchTrxLogs(searchCriteria);
-            List<VXTrxLog>    vxTrxLogs   = 
vXTrxLogsV2.getList().stream().map(VXTrxLogV2::toVXTrxLog).collect(Collectors.toList());
-            VXTrxLogList      ret         = new 
VXTrxLogList(validateXXTrxLogList(vxTrxLogs));
-
-            ret.setStartIndex(vXTrxLogsV2.getStartIndex());
-            ret.setPageSize(vXTrxLogsV2.getPageSize());
-            ret.setTotalCount(vXTrxLogsV2.getTotalCount());
-            ret.setResultSize(vXTrxLogsV2.getResultSize());
-            ret.setSortBy(vXTrxLogsV2.getSortBy());
-            ret.setSortType(vXTrxLogsV2.getSortType());
-
-            return ret;
+            return xTrxLogService.searchTrxLogs(searchCriteria);
         } else {
             throw restErrorUtil.create403RESTException("Permission Denied !");
         }
@@ -835,6 +866,84 @@ public List<VXTrxLog> validateXXTrxLogList(List<VXTrxLog> 
xTrxLogList) {
         return vXTrxLogs;
     }
 
+    public VXTrxLogV2List getTransactionReportV2(String transactionId) {
+        List<VXTrxLogV2> trxLogsV2 = 
xTrxLogService.findByTransactionId(transactionId);
+
+        return new VXTrxLogV2List(validateXXTrxLogV2List(trxLogsV2));
+    }
+
+    public List<VXTrxLogV2> validateXXTrxLogV2List(List<VXTrxLogV2> 
xTrxLogV2List) {
+        List<VXTrxLogV2> vXTrxLogV2s = new ArrayList<>();
+
+        for (VXTrxLogV2 vXTrxLogV2 : xTrxLogV2List) {
+            ObjectChangeInfo          objectChangeInfo = 
vXTrxLogV2.getChangeInfo();
+            List<AttributeChangeInfo> attrChanges      = (objectChangeInfo == 
null || objectChangeInfo.getAttributes() == null) ? Collections.emptyList() : 
objectChangeInfo.getAttributes();
+
+            for (AttributeChangeInfo attrChangeInfo : attrChanges) {
+                if (attrChangeInfo.getOldValue() == null || 
"null".equalsIgnoreCase(attrChangeInfo.getOldValue())) {
+                    attrChangeInfo.setOldValue("");
+                }
+
+                if (attrChangeInfo.getNewValue() == null || 
"null".equalsIgnoreCase(attrChangeInfo.getNewValue())) {
+                    attrChangeInfo.setNewValue("");
+                }
+
+                if 
("Password".equalsIgnoreCase(attrChangeInfo.getAttributeName())) {
+                    attrChangeInfo.setOldValue("*********");
+                    attrChangeInfo.setNewValue("***********");
+                }
+
+                if ("Connection 
Configurations".equalsIgnoreCase(attrChangeInfo.getAttributeName())) {
+                    if (attrChangeInfo.getOldValue() != null && 
attrChangeInfo.getOldValue().contains("password")) {
+                        String   tempPreviousStr = 
attrChangeInfo.getOldValue();
+                        String[] tempPreviousArr = 
attrChangeInfo.getOldValue().split(",");
+
+                        for (String tempPrevious : tempPreviousArr) {
+                            if (tempPrevious.contains("{\"password") && 
tempPrevious.contains("}")) {
+                                
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious, 
"{\"password\":\"*****\"}"));
+                                break;
+                            } else if (tempPrevious.contains("{\"password")) {
+                                
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious, 
"{\"password\":\"*****\""));
+                                break;
+                            } else if (tempPrevious.contains("\"password") && 
tempPrevious.contains("}")) {
+                                
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious, 
"\"password\":\"******\"}"));
+                                break;
+                            } else if (tempPrevious.contains("\"password")) {
+                                
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious, 
"\"password\":\"******\""));
+                                break;
+                            }
+                        }
+                    }
+
+                    if (attrChangeInfo.getNewValue() != null && 
attrChangeInfo.getNewValue().contains("password")) {
+                        String   tempNewStr = attrChangeInfo.getNewValue();
+                        String[] tempNewArr = 
attrChangeInfo.getNewValue().split(",");
+
+                        for (String tempNew : tempNewArr) {
+                            if (tempNew.contains("{\"password") && 
tempNew.contains("}")) {
+                                
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew, 
"{\"password\":\"*****\"}"));
+                                break;
+                            } else if (tempNew.contains("{\"password")) {
+                                
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew, 
"{\"password\":\"*****\""));
+                                break;
+                            } else if (tempNew.contains("\"password") && 
tempNew.contains("}")) {
+                                
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew, 
"\"password\":\"******\"}"));
+                                break;
+                            } else if (tempNew.contains("\"password")) {
+                                
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew, 
"\"password\":\"******\""));
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+
+            vXTrxLogV2s.add(vXTrxLogV2);
+        }
+
+        return vXTrxLogV2s;
+    }
+
     /*
      * (non-Javadoc)
      *
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
index b0dbef3e8..668389b25 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
@@ -23,6 +23,7 @@
 import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.common.db.BaseDao;
 import org.apache.ranger.entity.XXGdsDataset;
+import org.apache.ranger.plugin.model.RangerGds.GdsShareStatus;
 import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -88,6 +89,22 @@ public List<XXGdsDataset> findByDataShareId(Long 
dataShareId) {
         return ret != null ? ret : Collections.emptyList();
     }
 
+    public List<XXGdsDataset> findDatasetsWithDataShareInStatus(Long 
dataShareId, GdsShareStatus shareStatus) {
+        List<XXGdsDataset> ret = null;
+
+        if (dataShareId != null) {
+            try {
+                ret = 
getEntityManager().createNamedQuery("XXGdsDataset.findDatasetsWithDataShareInStatus",
 tClass)
+                        .setParameter("dataShareId", dataShareId)
+                        .setParameter("status", 
shareStatus.ordinal()).getResultList();
+            } catch (NoResultException e) {
+                LOG.debug("findDatasetsWithActiveDataShare({}): ", 
dataShareId, e);
+            }
+        }
+
+        return ret != null ? ret : Collections.emptyList();
+    }
+
     public List<XXGdsDataset> findByProjectId(Long projectId) {
         List<XXGdsDataset> ret = null;
 
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
index b1ff36ad0..0a98ee797 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
@@ -82,4 +82,20 @@ public List<Long> getDatasetPolicyIds(Long datasetId) {
 
         return ret;
     }
+
+    public Long getDatasetIdForPolicy(Long policyId) {
+        Long ret = null;
+
+        if (policyId != null) {
+            try {
+                ret = 
getEntityManager().createNamedQuery("XXGdsDatasetPolicyMap.getDatasetIdForPolicy",
 Long.class)
+                        .setParameter("policyId", policyId)
+                        .getSingleResult();
+            } catch (NoResultException e) {
+                // ignore
+            }
+        }
+
+        return ret;
+    }
 }
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
index a005519e7..1ed7259eb 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
@@ -23,6 +23,7 @@
 import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.common.db.BaseDao;
 import org.apache.ranger.entity.XXGdsProject;
+import org.apache.ranger.plugin.model.RangerGds;
 import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -88,6 +89,34 @@ public List<XXGdsProject> findByDatasetId(Long datasetId) {
         return ret != null ? ret : Collections.emptyList();
     }
 
+    public List<XXGdsProject> findProjectsWithDatasetInStatus(Long datasetId, 
RangerGds.GdsShareStatus shareStatus) {
+        List<XXGdsProject> ret = null;
+
+        try {
+            ret = 
getEntityManager().createNamedQuery("XXGdsProject.findProjectsWithDatasetInStatus",
 tClass)
+                    .setParameter("datasetId", datasetId)
+                    .setParameter("status", 
shareStatus.ordinal()).getResultList();
+        } catch (NoResultException e) {
+            LOG.debug("findProjectsWithDatasetInStatus({}): ", datasetId, e);
+        }
+
+        return ret != null ? ret : Collections.emptyList();
+    }
+
+    public List<XXGdsProject> findProjectsWithDataShareInStatus(Long 
dataShareId, RangerGds.GdsShareStatus shareStatus) {
+        List<XXGdsProject> ret = null;
+
+        try {
+            ret = 
getEntityManager().createNamedQuery("XXGdsProject.findProjectsWithDataShareInStatus",
 tClass)
+                    .setParameter("dataShareId", dataShareId)
+                    .setParameter("status", 
shareStatus.ordinal()).getResultList();
+        } catch (NoResultException e) {
+            LOG.debug("findProjectsWithDataShareInStatus({}): ", dataShareId, 
e);
+        }
+
+        return ret != null ? ret : Collections.emptyList();
+    }
+
     public List<Long> findServiceIdsForProject(Long projectId) {
         List<Long> ret = null;
 
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
index b3529e840..694e0cc8a 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
@@ -82,4 +82,20 @@ public List<Long> getProjectPolicyIds(Long projectId) {
 
         return ret;
     }
+
+    public Long getProjectIdForPolicy(Long policyId) {
+        Long ret = null;
+
+        if (policyId != null) {
+            try {
+                ret = 
getEntityManager().createNamedQuery("XXGdsProjectPolicyMap.getProjectIdForPolicy",
 Long.class)
+                        .setParameter("policyId", policyId)
+                        .getSingleResult();
+            } catch (NoResultException e) {
+                // ignore
+            }
+        }
+
+        return ret;
+    }
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
index d29e44eff..46ee557c1 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
@@ -58,6 +58,7 @@
 import org.apache.ranger.view.VXResourceList;
 import org.apache.ranger.view.VXResponse;
 import org.apache.ranger.view.VXTrxLogList;
+import org.apache.ranger.view.VXTrxLogV2List;
 import org.apache.ranger.view.VXUgsyncAuditInfoList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -504,20 +505,21 @@ public VXPolicyExportAuditList 
searchXPolicyExportAudits(@Context HttpServletReq
     @Produces("application/json")
     @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + 
RangerAPIList.GET_REPORT_LOGS + "\")")
     public VXTrxLogList getReportLogs(@Context HttpServletRequest request) {
-        SearchCriteria searchCriteria = 
searchUtil.extractCommonCriterias(request, xTrxLogService.getSortFields());
-
-        searchUtil.extractInt(request, searchCriteria, "objectClassType", 
"audit type.");
-        searchUtil.extractInt(request, searchCriteria, "objectId", "Object 
ID");
-        searchUtil.extractString(request, searchCriteria, "attributeName", 
"Attribute Name", StringUtil.VALIDATION_TEXT);
-        searchUtil.extractString(request, searchCriteria, "action", "CRUD 
Action Type", StringUtil.VALIDATION_TEXT);
-        searchUtil.extractString(request, searchCriteria, "sessionId", 
"Session Id", StringUtil.VALIDATION_TEXT);
-        searchUtil.extractString(request, searchCriteria, "owner", "Owner", 
StringUtil.VALIDATION_TEXT);
-        searchUtil.extractDate(request, searchCriteria, "startDate", 
"Trasaction date since", "MM/dd/yyyy");
-        searchUtil.extractDate(request, searchCriteria, "endDate", "Trasaction 
date till", "MM/dd/yyyy");
+        SearchCriteria searchCriteria = extractSearchCriteriaFrom(request);
 
         return assetMgr.getReportLogs(searchCriteria);
     }
 
+    @GET
+    @Path("/v2/report")
+    @Produces("application/json")
+    @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + 
RangerAPIList.GET_REPORT_LOGS + "\")")
+    public VXTrxLogV2List getReportLogsV2(@Context HttpServletRequest request) 
{
+        SearchCriteria searchCriteria = extractSearchCriteriaFrom(request);
+
+        return assetMgr.getReportLogsV2(searchCriteria);
+    }
+
     @GET
     @Path("/report/{transactionId}")
     @Produces("application/json")
@@ -526,6 +528,14 @@ public VXTrxLogList getTransactionReport(@Context 
HttpServletRequest request, @P
         return assetMgr.getTransactionReport(transactionId);
     }
 
+    @GET
+    @Path("/v2/report/{transactionId}")
+    @Produces("application/json")
+    @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + 
RangerAPIList.GET_TRANSACTION_REPORT + "\")")
+    public VXTrxLogV2List getTransactionReportV2(@Context HttpServletRequest 
request, @PathParam("transactionId") String transactionId) {
+        return assetMgr.getTransactionReportV2(transactionId);
+    }
+
     @GET
     @Path("/accessAudit")
     @Produces("application/json")
@@ -683,4 +693,19 @@ public VXUgsyncAuditInfoList getUgsyncAudits(@Context 
HttpServletRequest request
     public VXUgsyncAuditInfoList 
getUgsyncAuditsBySyncSource(@PathParam("syncSource") String syncSource) {
         return assetMgr.getUgsyncAuditsBySyncSource(syncSource);
     }
+
+    private SearchCriteria extractSearchCriteriaFrom(HttpServletRequest 
request) {
+        SearchCriteria searchCriteria = 
searchUtil.extractCommonCriterias(request, xTrxLogService.getSortFields());
+
+        searchUtil.extractInt(request, searchCriteria, "objectClassType", 
"audit type.");
+        searchUtil.extractInt(request, searchCriteria, "objectId", "Object 
ID");
+        searchUtil.extractString(request, searchCriteria, "attributeName", 
"Attribute Name", StringUtil.VALIDATION_TEXT);
+        searchUtil.extractString(request, searchCriteria, "action", "CRUD 
Action Type", StringUtil.VALIDATION_TEXT);
+        searchUtil.extractString(request, searchCriteria, "sessionId", 
"Session Id", StringUtil.VALIDATION_TEXT);
+        searchUtil.extractString(request, searchCriteria, "owner", "Owner", 
StringUtil.VALIDATION_TEXT);
+        searchUtil.extractDate(request, searchCriteria, "startDate", 
"Trasaction date since", "MM/dd/yyyy");
+        searchUtil.extractDate(request, searchCriteria, "endDate", "Trasaction 
date till", "MM/dd/yyyy");
+
+        return searchCriteria;
+    }
 }
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
 
b/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
index edf514b1f..888b470ab 100755
--- 
a/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
@@ -17,12 +17,24 @@
 
 package org.apache.ranger.service;
 
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.common.PropertiesUtil;
 import org.apache.ranger.common.view.VTrxLogAttr;
 import org.apache.ranger.entity.XXDBBase;
+import org.apache.ranger.entity.XXGdsDataset;
+import org.apache.ranger.entity.XXGdsProject;
 import org.apache.ranger.entity.XXTrxLogV2;
 import org.apache.ranger.plugin.model.RangerBaseModelObject;
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataShare;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataShareInDataset;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataset;
+import org.apache.ranger.plugin.model.RangerGds.RangerDatasetInProject;
+import org.apache.ranger.plugin.model.RangerGds.RangerProject;
+import org.apache.ranger.plugin.model.RangerGds.RangerSharedResource;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.util.JsonUtilsV2;
 import org.apache.ranger.util.RangerEnumUtil;
 import org.apache.ranger.view.VXTrxLogV2.ObjectChangeInfo;
@@ -51,6 +63,15 @@ public abstract class RangerAuditedModelService<T extends 
XXDBBase, V extends Ra
     @Autowired
     RangerDataHistService dataHistService;
 
+    @Autowired
+    RangerGdsDatasetService datasetService;
+
+    @Autowired
+    RangerGdsDataShareService dataShareService;
+
+    @Autowired
+    RangerGdsProjectService projectService;
+
     @Autowired
     RangerEnumUtil xaEnumUtil;
 
@@ -124,10 +145,10 @@ public void createTransactionLog(XXTrxLogV2 trxLog) {
     }
 
     public void createTransactionLog(V obj, V oldObj, int action) {
-        List<XXTrxLogV2> trxLogs = getTransactionLogs(obj, oldObj, action);
+        List<List<XXTrxLogV2>> trxLogs = getTransactionLogs(obj, oldObj, 
action);
 
-        if (trxLogs != null) {
-            bizUtil.createTrxLog(trxLogs);
+        for (List<XXTrxLogV2> trxLog : trxLogs) {
+            bizUtil.createTrxLog(trxLog);
         }
     }
 
@@ -151,12 +172,12 @@ public String getTrxLogAttrValue(V obj, VTrxLogAttr 
trxLogAttr) {
         return trxLogAttr.getAttrValue(obj, xaEnumUtil);
     }
 
-    private List<XXTrxLogV2> getTransactionLogs(V obj, V oldObj, int action) {
+    private List<List<XXTrxLogV2>> getTransactionLogs(V obj, V oldObj, int 
action) {
         if (obj == null || (action == OPERATION_UPDATE_CONTEXT && oldObj == 
null)) {
-            return null;
+            return Collections.emptyList();
         }
 
-        List<XXTrxLogV2> ret = new ArrayList<>();
+        List<List<XXTrxLogV2>> ret = new ArrayList<>();
 
         try {
             ObjectChangeInfo objChangeInfo = new ObjectChangeInfo();
@@ -165,9 +186,11 @@ private List<XXTrxLogV2> getTransactionLogs(V obj, V 
oldObj, int action) {
                 processFieldToCreateTrxLog(trxLog, obj, oldObj, action, 
objChangeInfo);
             }
 
-            if (objChangeInfo.getAttributes() != null && 
!objChangeInfo.getAttributes().isEmpty()) {
-                ret.add(new XXTrxLogV2(classType, obj.getId(), 
getObjectName(obj), getParentObjectType(obj, oldObj), getParentObjectId(obj, 
oldObj), getParentObjectName(obj, oldObj), toActionString(action), 
JsonUtilsV2.objToJson(objChangeInfo)));
+            if (CollectionUtils.isNotEmpty(objChangeInfo.getAttributes())) {
+                addXXTrxLogV2(obj, oldObj, action, objChangeInfo, ret);
             }
+
+            addTransactionLogsOnImpactedObjects(obj, oldObj, action, 
objChangeInfo, ret);
         } catch (Exception excp) {
             LOG.warn("failed to get transaction log for object: type={}, 
id={}", obj.getClass().getName(), obj.getId(), excp);
         }
@@ -246,4 +269,117 @@ private String toActionString(int action) {
 
         return "unknown";
     }
+
+    protected void addXXTrxLogV2(V obj, V oldObj, int action, ObjectChangeInfo 
objChangeInfo, List<List<XXTrxLogV2>> ret) {
+        try {
+            if (obj != null) {
+                XXTrxLogV2 trxLog = new XXTrxLogV2(classType, obj.getId(), 
getObjectName(obj), getParentObjectType(obj, oldObj), getParentObjectId(obj, 
oldObj), getParentObjectName(obj, oldObj), toActionString(action), 
JsonUtilsV2.objToJson(objChangeInfo));
+
+                ret.add(Collections.singletonList(trxLog));
+            }
+        } catch (Exception excp) {
+            LOG.warn("failed to get transaction log for object: type={}, 
id={}", obj.getClass().getName(), obj.getId(), excp);
+        }
+    }
+
+    private void addTransactionLogsOnImpactedObjects(V obj, V oldObj, int 
action, ObjectChangeInfo objChangeInfo, List<List<XXTrxLogV2>> ret) {
+        V auditedObj = (action == OPERATION_DELETE_CONTEXT || action == 
OPERATION_IMPORT_DELETE_CONTEXT) ? oldObj : obj;
+
+        if (auditedObj != null) {
+            ObjectChangeInfo changeSourceInfo = 
getChangeSourceInfo(auditedObj, action, objChangeInfo);
+
+            if (auditedObj instanceof RangerSharedResource) {
+                Long            dataShareId = ((RangerSharedResource) 
auditedObj).getDataShareId();
+                RangerDataShare dataShare   = 
dataShareService.read(dataShareId);
+
+                dataShareService.addXXTrxLogV2(dataShare, dataShare, 
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+
+                List<XXGdsDataset> datasets = 
daoMgr.getXXGdsDataset().findDatasetsWithDataShareInStatus(dataShareId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                if (CollectionUtils.isNotEmpty(datasets)) {
+                    List<XXGdsProject> projects = 
daoMgr.getXXGdsProject().findProjectsWithDataShareInStatus(dataShareId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                    logImpactedDatasets(datasets, changeSourceInfo, ret);
+                    logImpactedProjects(projects, changeSourceInfo, ret);
+                }
+            } else if (auditedObj instanceof RangerDataShare) {
+                Long               dataShareId = auditedObj.getId();
+                List<XXGdsDataset> datasets    = 
daoMgr.getXXGdsDataset().findDatasetsWithDataShareInStatus(dataShareId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                if (CollectionUtils.isNotEmpty(datasets)) {
+                    List<XXGdsProject> projects = 
daoMgr.getXXGdsProject().findProjectsWithDataShareInStatus(dataShareId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                    logImpactedDatasets(datasets, changeSourceInfo, ret);
+                    logImpactedProjects(projects, changeSourceInfo, ret);
+                }
+            } else if (auditedObj instanceof RangerDataShareInDataset) {
+                Long          datasetId = ((RangerDataShareInDataset) 
auditedObj).getDatasetId();
+                RangerDataset dataset   = datasetService.read(datasetId);
+
+                datasetService.addXXTrxLogV2(dataset, dataset, 
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+
+                List<XXGdsProject> projects = 
daoMgr.getXXGdsProject().findProjectsWithDatasetInStatus(datasetId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                logImpactedProjects(projects, changeSourceInfo, ret);
+            } else if (auditedObj instanceof RangerDataset) {
+                Long datasetId = auditedObj.getId();
+
+                List<XXGdsProject> projects = 
daoMgr.getXXGdsProject().findProjectsWithDatasetInStatus(datasetId, 
RangerGds.GdsShareStatus.ACTIVE);
+
+                logImpactedProjects(projects, changeSourceInfo, ret);
+            } else if (auditedObj instanceof RangerDatasetInProject) {
+                Long          projectId = ((RangerDatasetInProject) 
auditedObj).getProjectId();
+                RangerProject project   = projectService.read(projectId);
+
+                projectService.addXXTrxLogV2(project, project, 
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+            } else if (auditedObj instanceof RangerPolicy) {
+                Long datasetId = 
daoMgr.getXXGdsDatasetPolicyMap().getDatasetIdForPolicy(auditedObj.getId());
+
+                if (datasetId != null) {
+                    RangerDataset dataset = datasetService.read(datasetId);
+
+                    datasetService.addXXTrxLogV2(dataset, dataset, 
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+                } else {
+                    Long projectId = 
daoMgr.getXXGdsProjectPolicyMap().getProjectIdForPolicy(auditedObj.getId());
+
+                    if (projectId != null) {
+                        RangerProject project = projectService.read(projectId);
+
+                        projectService.addXXTrxLogV2(project, project, 
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+                    }
+                }
+            }
+        }
+    }
+
+    private ObjectChangeInfo getChangeSourceInfo(V sourceObj, int action, 
ObjectChangeInfo objChangeInfo) {
+        ObjectChangeInfo ret = new ObjectChangeInfo();
+
+        ret.addAttribute("_objectId", null, String.valueOf(sourceObj.getId()));
+        ret.addAttribute("_objectClassType", null, String.valueOf(classType));
+        ret.addAttribute("_objectClassName", null, 
sourceObj.getClass().getSimpleName());
+        ret.addAttribute("_changeType", null, toActionString(action));
+
+        if (objChangeInfo.getAttributes() != null) {
+            ret.getAttributes().addAll(objChangeInfo.getAttributes());
+        }
+
+        return ret;
+    }
+
+    private void logImpactedDatasets(List<XXGdsDataset> xxDatasets, 
ObjectChangeInfo changedObjInfo, List<List<XXTrxLogV2>> ret) {
+        for (XXGdsDataset xxDataset : xxDatasets) {
+            RangerDataset dataset = 
datasetService.getPopulatedViewObject(xxDataset);
+
+            datasetService.addXXTrxLogV2(dataset, dataset, 
OPERATION_UPDATE_CONTEXT, changedObjInfo, ret);
+        }
+    }
+
+    private void logImpactedProjects(List<XXGdsProject> xxProjects, 
ObjectChangeInfo changedObjInfo, List<List<XXTrxLogV2>> ret) {
+        for (XXGdsProject xxProject : xxProjects) {
+            RangerProject project = 
projectService.getPopulatedViewObject(xxProject);
+
+            projectService.addXXTrxLogV2(project, project, 
OPERATION_UPDATE_CONTEXT, changedObjInfo, ret);
+        }
+    }
 }
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml 
b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index 3559877d5..1cc89ee4a 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -2211,6 +2211,14 @@
                </query>
        </named-query>
 
+       <named-query name="XXGdsDataset.findDatasetsWithDataShareInStatus">
+               <query>select obj from XXGdsDataset obj, 
XXGdsDataShareInDataset dsid
+                       where dsid.dataShareId = :dataShareId
+                         and dsid.datasetId   = obj.id
+                         and dsid.status      = :status
+               </query>
+       </named-query>
+
        <named-query name="XXGdsDataset.findByProjectId">
                <query>select obj from XXGdsDataset obj, XXGdsDatasetInProject 
dip
                        where dip.projectId = :projectId
@@ -2244,6 +2252,22 @@
                          and dip.projectId = obj.id</query>
        </named-query>
 
+       <named-query name="XXGdsProject.findProjectsWithDatasetInStatus">
+               <query>SELECT obj FROM XXGdsProject obj, XXGdsDatasetInProject 
dip
+                       WHERE dip.datasetId = :datasetId
+                         AND dip.projectId = obj.id
+                         AND dip.status    = :status</query>
+       </named-query>
+
+       <named-query name="XXGdsProject.findProjectsWithDataShareInStatus">
+               <query>SELECT DISTINCT obj FROM XXGdsProject obj, 
XXGdsDatasetInProject dip, XXGdsDataShareInDataset dshid
+                       WHERE dshid.dataShareId = :dataShareId
+                         AND dshid.status      = :status
+                         AND dip.datasetId     = dshid.datasetId
+                         AND dip.projectId     = obj.id
+                         AND dip.status        = :status</query>
+       </named-query>
+
        <named-query name="XXGdsProject.findServiceIds">
                <query>SELECT DISTINCT(dsh.serviceId) FROM XXGdsDataShare dsh, 
XXGdsDataShareInDataset dshid, XXGdsDatasetInProject dip
                        WHERE dip.projectId     = :projectId
@@ -2387,6 +2411,10 @@
                <query>SELECT obj.policyId FROM XXGdsDatasetPolicyMap obj WHERE 
obj.datasetId = :datasetId</query>
        </named-query>
 
+       <named-query name="XXGdsDatasetPolicyMap.getDatasetIdForPolicy">
+               <query>SELECT obj.datasetId FROM XXGdsDatasetPolicyMap obj 
WHERE obj.policyId = :policyId</query>
+       </named-query>
+
        <named-query name="XXGdsProjectPolicyMap.getProjectPolicyMap">
                <query>SELECT obj FROM XXGdsProjectPolicyMap obj WHERE 
obj.projectId = :projectId AND obj.policyId = :policyId</query>
        </named-query>
@@ -2398,4 +2426,8 @@
        <named-query name="XXGdsProjectPolicyMap.getProjectPolicyIds">
                <query>SELECT obj.policyId FROM XXGdsProjectPolicyMap obj WHERE 
obj.projectId = :projectId</query>
        </named-query>
+
+       <named-query name="XXGdsProjectPolicyMap.getProjectIdForPolicy">
+               <query>SELECT obj.projectId FROM XXGdsProjectPolicyMap obj 
WHERE obj.policyId = :policyId</query>
+       </named-query>
 </entity-mappings>
diff --git 
a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java 
b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
index 7bddf1874..7d87bb701 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
@@ -59,6 +59,8 @@
 import org.apache.ranger.view.VXResponse;
 import org.apache.ranger.view.VXTrxLog;
 import org.apache.ranger.view.VXTrxLogList;
+import org.apache.ranger.view.VXTrxLogV2;
+import org.apache.ranger.view.VXTrxLogV2List;
 import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Rule;
@@ -510,6 +512,41 @@ public void testGetTransactionReport() {
         Mockito.verify(assetMgr).getTransactionReport(transactionId);
     }
 
+    @Test
+    public void testGetReportLogsV2() {
+        SearchCriteria   searchCriteria = new SearchCriteria();
+        List<SortField>  sortFields     = xTrxLogService.getSortFields();
+        VXTrxLogV2List   vXTrxLogV2List = new VXTrxLogV2List(new 
ArrayList<>());
+
+        Mockito.when(searchUtil.extractCommonCriterias(request, 
sortFields)).thenReturn(searchCriteria);
+        Mockito.when(searchUtil.extractString(Mockito.any(), Mockito.any(), 
Mockito.anyString(), Mockito.anyString(), 
Mockito.anyString())).thenReturn("test");
+        Mockito.when(searchUtil.extractInt(Mockito.any(), Mockito.any(), 
Mockito.anyString(), Mockito.anyString())).thenReturn(8);
+        Mockito.when(searchUtil.extractDate(Mockito.any(), Mockito.any(), 
Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(new 
Date());
+        
Mockito.when(assetMgr.getReportLogsV2(searchCriteria)).thenReturn(vXTrxLogV2List);
+
+        VXTrxLogV2List expectedVXTrxLogV2List = 
assetREST.getReportLogsV2(request);
+
+        Assert.assertEquals(vXTrxLogV2List, expectedVXTrxLogV2List);
+        Mockito.verify(searchUtil, 
Mockito.times(4)).extractString(Mockito.any(), Mockito.any(), 
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
+        Mockito.verify(searchUtil, Mockito.times(2)).extractInt(Mockito.any(), 
Mockito.any(), Mockito.anyString(), Mockito.anyString());
+        Mockito.verify(searchUtil, 
Mockito.times(2)).extractDate(Mockito.any(), Mockito.any(), 
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
+        Mockito.verify(assetMgr).getReportLogsV2(searchCriteria);
+        Mockito.verify(searchUtil).extractCommonCriterias(request, sortFields);
+    }
+
+    @Test
+    public void testGetTransactionReportV2() {
+        VXTrxLogV2List   vXTrxLogV2List = new VXTrxLogV2List(new 
ArrayList<>());
+        String           transactionId  = "123456";
+
+        
Mockito.when(assetMgr.getTransactionReportV2(transactionId)).thenReturn(vXTrxLogV2List);
+
+        VXTrxLogV2List expectedVXTrxLogList = 
assetREST.getTransactionReportV2(request, transactionId);
+
+        Assert.assertEquals(vXTrxLogV2List, expectedVXTrxLogList);
+        Mockito.verify(assetMgr).getTransactionReportV2(transactionId);
+    }
+
     @Test
     public void testGetAccessLogs() {
         SearchCriteria      searchCriteria    = new SearchCriteria();


Reply via email to