You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by dh...@apache.org on 2025/05/13 10:32:26 UTC

(ranger) 06/08: RANGER-5170: enhanced GDS admin audits to record the changes on impacted objects as well

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 <ra...@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 <ma...@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();