mneethiraj commented on code in PR #962:
URL: https://github.com/apache/ranger/pull/962#discussion_r3284092749


##########
security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java:
##########
@@ -101,4 +110,29 @@ public List<XXResourceDef> findByParentResId(Long 
parentId) {
             return new ArrayList<>();
         }
     }
+
+    public Map<String, XXResourceDef> 
findXXResourceDefsByNameAndPolicyId(Set<String> names, Long policyId) {

Review Comment:
   The caller of `findXXResourceDefsByNameAndPolicyId()` only needs resourceId 
(`XXResourceDef.id`) for each resource name. Retrieving only `id` from the 
database will help improve the performance.
   
   1. I suggest updating & renaming the method from:
   ```
   public Map<String, XXResourceDef> 
findXXResourceDefsByNameAndPolicyId(Set<String> names, Long policyId)
   ```
   to:
   ```
   public Map<String, Long> findResourceDefIdsByNameAndPolicyId(Set<String> 
names, Long policyId)
   ```
   
   2. Update the named query `XXResourceDef.findByNamesAndPolicyId` to return 
`id` instead of `XXResourceDef`.
   
   3. Review similar updates to following named queries and corresponding Dao 
methods that use them:
       - `XXAccessTypeDef.findByNamesAndServiceId`
       - `XXPolicyConditionDef.findByServiceDefIdAndNames`
       - `XXDataMaskTypeDef.findByNamesAndServiceId`



##########
security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefRoleDao.java:
##########
@@ -133,4 +135,34 @@ public void deleteByPolicyId(Long policyId) {
 
         batchDeleteByIds("XXPolicyRefRole.deleteByIds", ids, "ids");
     }
+
+    public Map<String, Long> findRoleNameIdByPolicyId(Long policyId) {
+        if (policyId == null) {
+            return Collections.emptyMap();
+        }
+        try {
+            List<Object[]> results = getEntityManager()
+                    
.createNamedQuery("XXPolicyRefRole.findRoleNameIdByPolicyId", Object[].class)
+                    .setParameter("policyId", policyId)
+                    .getResultList();
+
+            Map<String, Long> roleNameIdMap = new HashMap<>();

Review Comment:
   To be consistent, consider using streams to convert `results` ito 
`roleNameIdMap` - similar to `XXRoleDao.getIdsByRoleNames()`.



##########
security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefUserDao.java:
##########
@@ -133,4 +135,34 @@ public void deleteByPolicyId(Long policyId) {
 
         batchDeleteByIds("XXPolicyRefUser.deleteByIds", ids, "ids");
     }
+
+    public Map<String, Long> findUserNameIdByPolicyId(Long policyId) {
+        if (policyId == null) {
+            return Collections.emptyMap();
+        }
+        try {
+            List<Object[]> results = getEntityManager()
+                    
.createNamedQuery("XXPolicyRefUser.findUserNameIdByPolicyId", Object[].class)
+                    .setParameter("policyId", policyId)
+                    .getResultList();
+
+            Map<String, Long> userNameIdMap = new HashMap<>();

Review Comment:
   To be consistent, consider using streams to convert `results` ito 
`userNameIdMap` - similar to `XXRoleDao.getIdsByRoleNames()`.



##########
security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefGroupDao.java:
##########
@@ -120,4 +122,34 @@ public void deleteByPolicyId(Long policyId) {
 
         batchDeleteByIds("XXPolicyRefGroup.deleteByIds", ids, "ids");
     }
+
+    public Map<String, Long> findGroupNameByPolicyId(Long policyId) {
+        if (policyId == null) {
+            return Collections.emptyMap();
+        }
+        try {
+            List<Object[]> results = getEntityManager()
+                    
.createNamedQuery("XXPolicyRefGroup.findGroupNameByPolicyId", Object[].class)
+                    .setParameter("policyId", policyId)
+                    .getResultList();
+
+            Map<String, Long> groupNameIdMap = new HashMap<>();

Review Comment:
   To be consistent, consider using streams to convert `results` ito 
`groupNameIdMap` - similar to `XXRoleDao.getIdsByRoleNames()`.



##########
security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java:
##########
@@ -175,167 +181,171 @@ public void createNewPolMappingForRefTable(RangerPolicy 
policy, XXPolicy xPolicy
             }
         }
 
-        List<XXPolicyRefResource> xPolResources = new ArrayList<>();
-
-        for (String resource : resourceNames) {
-            XXResourceDef xResDef = 
daoMgr.getXXResourceDef().findByNameAndPolicyId(resource, policy.getId());
+        if (isCleanupRefTablesNeeded) {
+            cleanupRefTablesForUpdate(policyId, userNames, roleNames, 
groupNames);
+        }
 
-            if (xResDef == null) {
-                throw new Exception(resource + ": is not a valid 
resource-type. policy='" + policy.getName() + "' service='" + 
policy.getService() + "'");
+        if (CollectionUtils.isNotEmpty(resourceNames)) {
+            List<XXPolicyRefResource> xPolResources = new ArrayList<>();
+            Map<String, XXResourceDef> nameToResDefMap = 
daoMgr.getXXResourceDef().findXXResourceDefsByNameAndPolicyId(resourceNames, 
policy.getId());
+            for (String resource : resourceNames) {
+                XXResourceDef xResDef = nameToResDefMap.get(resource);
+                if (xResDef == null) {
+                    throw new Exception(resource + ": is not a valid 
resource-type. policy='" + policy.getName() + "' service='" + 
policy.getService() + "'");
+                }
+                XXPolicyRefResource xPolRes = new XXPolicyRefResource();
+                xPolRes.setPolicyId(policy.getId());
+                xPolRes.setResourceDefId(xResDef.getId());
+                xPolRes.setResourceName(resource);
+                xPolResources.add(xPolRes);
             }
-
-            XXPolicyRefResource xPolRes = new XXPolicyRefResource();
-
-            xPolRes.setPolicyId(policy.getId());
-            xPolRes.setResourceDefId(xResDef.getId());
-            xPolRes.setResourceName(resource);
-
-            xPolResources.add(xPolRes);
+            batchInsert(xPolResources, daoMgr.getXXPolicyRefResource(), 
oldBulkMode);
         }
 
-        daoMgr.getXXPolicyRefResource().batchCreate(xPolResources);
-
         if (createPrincipalsIfAbsent && !rangerBizUtil.checkAdminAccess()) {
             LOG.warn("policy={}: createPrincipalIfAbsent=true, but current 
user does not have admin privileges!", policy.getName());
 
             createPrincipalsIfAbsent = false;
         }
 
         List<XXPolicyRefRole> xPolRoles = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(roleNames)) {
+            LOG.debug("x_policy_ref_role - New role entries to insert for 
policy ID {}: {}", policyId, roleNames);
+            Set<String> filteredRoleNames = roleNames.stream()
+                    .filter(str -> !StringUtils.isBlank(str))
+                    .collect(Collectors.toSet());
+            Map<String, Long> roleNameIdMap = 
daoMgr.getXXRole().getIdsByRoleNames(filteredRoleNames);
+            for (String roleName : filteredRoleNames) {
+                PolicyPrincipalAssociator associator = new 
PolicyPrincipalAssociator(PRINCIPAL_TYPE.ROLE, roleName, xPolicy, 
roleNameIdMap.get(roleName), null, null, xPolRoles);

Review Comment:
   Instead of having `PolicyPrincipalAssociator` take 3 collection parameters 
and populating one of them in `doAssociate()` call, consider:
   - creating 3 classes `PolicyRoleAssociator`, `PolicyGroupAssociator` and 
`PolicyUserAssociator`
   - add method `getPolicyRef()` to return 
XXPolicyRefRole/XXPolicyRefGroup/XXPolicyRefUser when the policy exists
   - add method `createPolicyRef()` to create 
XXPolicyRefRole/XXPolicyRefGroup/XXPolicyRefUser when the policy exists
   
   ```
   Long                 roleId     = roleNameIdMap.get(roleName);
   PolicyRoleAssociator associator = new PolicyRoleAssociator(roleName, roleId, 
xPolicy);
   
   if (roleId != null) {
     XXPolicyRoleRef roleRef = associator.getPolicyRef();
   
     if (roleRef != null) {
       xPolRoles.add(roleRef);
     }
   } else if (createPrincipalsIfAbsent) {
     
rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
   } else {
     VXResponse gjResponse = new VXResponse();
     ...
     throw restErrorUtil.generateRESTException(gjResponse);
   }
   ```
   
   Review handling of groups and users references as well - line 243 and 268.



##########
security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java:
##########
@@ -101,4 +110,29 @@ public List<XXResourceDef> findByParentResId(Long 
parentId) {
             return new ArrayList<>();
         }
     }
+
+    public Map<String, XXResourceDef> 
findXXResourceDefsByNameAndPolicyId(Set<String> names, Long policyId) {
+        Map<String, XXResourceDef> ret = Collections.emptyMap();
+        if (policyId == null || CollectionUtils.isEmpty(names)) {
+            return ret;

Review Comment:
   Consider having a single `return` statement in a method.



##########
security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java:
##########
@@ -356,17 +366,151 @@ public Boolean cleanupRefTables(RangerPolicy policy) {
         return true;
     }
 
+    /**
+     * Cleans up reference tables for a given policy before updating it.
+     * This includes handling policy reference users, roles, and other
+     * associated reference entities like resources, groups, access types,
+     * conditions, and data mask types.
+     *
+     * @param policyId      ID of the policy being updated.
+     * @param policyUsers   Set of usernames associated with the updated 
policy.
+     * @param policyRoles   Set of role names associated with the updated 
policy.
+     * @param policyGroups   Set of group names associated with the updated 
policy.
+     * @return              true if cleanup was successful.
+     */
+    public Boolean cleanupRefTablesForUpdate(Long policyId, Set<String> 
policyUsers, Set<String> policyRoles, Set<String> policyGroups) {
+        XXPolicyRefUserDao xPolicyRefUserDao = daoMgr.getXXPolicyRefUser();
+        XXPolicyRefRoleDao xxPolicyRefRoleDao = daoMgr.getXXPolicyRefRole();
+        XXPolicyRefGroupDao xxPolicyRefGroupDao = daoMgr.getXXPolicyRefGroup();
+
+        Map<String, Long> policyUserNameIdMap   = 
xPolicyRefUserDao.findUserNameIdByPolicyId(policyId);

Review Comment:
   Consider moving lines 386, 387 and 388 into cleanupPolicyRefUsers(), 
cleanupPolicyRefRoles() and cleanupPolicyRefGroups() respectively - to improve 
readability.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to