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

pradeep 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 277f461  RANGER-3576: service creation is failing intermittently due 
to DB unique key constraint violation
277f461 is described below

commit 277f4610118c2cdb6ce9e2bf31e60f4d5b986c59
Author: pradeep <prad...@apache.org>
AuthorDate: Sun Jan 9 21:49:22 2022 +0530

    RANGER-3576: service creation is failing intermittently due to DB unique 
key constraint violation
---
 .../main/java/org/apache/ranger/biz/XUserMgr.java  | 183 +++++++++++----------
 .../java/org/apache/ranger/biz/TestXUserMgr.java   |  68 ++++----
 .../ranger/ugsyncutil/model/GroupUserInfo.java     |   2 +-
 3 files changed, 140 insertions(+), 113 deletions(-)

diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java 
b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index 0eb582c..853007b 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -35,6 +35,7 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.biz.ServiceDBStore.REMOVE_REF_TYPE;
 import org.apache.ranger.common.*;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
 import org.apache.ranger.entity.XXGroupPermission;
 import org.apache.ranger.entity.XXModuleDef;
 import org.apache.ranger.entity.XXUserPermission;
@@ -160,6 +161,9 @@ public class XUserMgr extends XUserMgrBase {
        StringUtil stringUtil;
 
        @Autowired
+       RangerTransactionSynchronizationAdapter 
transactionSynchronizationAdapter;
+
+       @Autowired
        @Qualifier(value = "transactionManager")
        PlatformTransactionManager txManager;
 
@@ -2513,94 +2517,19 @@ public class XUserMgr extends XUserMgrBase {
                        throw restErrorUtil.createRESTException("Please provide 
a valid username.",MessageEnums.INVALID_INPUT_DATA);
                }
 
-               VXUser vXUser = null;
-               VXPortalUser vXPortalUser=null;
                XXUser xxUser = daoManager.getXXUser().findByUserName(userName);
-               XXPortalUser xXPortalUser = 
daoManager.getXXPortalUser().findByLoginId(userName);
-               String actualPassword = "";
-               if(xxUser!=null){
-                       vXUser = xUserService.populateViewBean(xxUser);
-                       return vXUser;
+               if (xxUser == null) {
+                       
transactionSynchronizationAdapter.executeOnTransactionCommit(new 
ExternalUserCreator(userName));
                }
-               if(xxUser==null){
-                       vXUser=new VXUser();
-                       vXUser.setName(userName);
-                       vXUser.setUserSource(RangerCommonEnums.USER_EXTERNAL);
-                       vXUser.setDescription(vXUser.getName());
-                       actualPassword = vXUser.getPassword();
-               }
-               if(xXPortalUser==null){
-            int noOfRetries = 0;
-                       do {
-                           try {
-                    TransactionTemplate txTemplate = new 
TransactionTemplate(txManager);
-                    
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
-                    noOfRetries++;
-                                       final VXUser vxUserFinal = vXUser;
-                    xXPortalUser = txTemplate.execute(new 
TransactionCallback<XXPortalUser>() {
-                        @Override
-                        public XXPortalUser doInTransaction(TransactionStatus 
status) {
-                            XXPortalUser ret = 
daoManager.getXXPortalUser().findByLoginId(userName);
-                            if (ret == null) {
-                                                               if 
(logger.isDebugEnabled()) {
-                                                                       
logger.debug("createServiceConfigUser(): Couldn't find " + userName + " and 
hence creating user in x_portal_user table");
-                                                               }
-                                                               VXPortalUser 
vXPortalUser=new VXPortalUser();
-                                                               
vXPortalUser.setLoginId(userName);
-                                                               
vXPortalUser.setEmailAddress(vxUserFinal.getEmailAddress());
-                                                               
vXPortalUser.setFirstName(vxUserFinal.getFirstName());
-                                                               
vXPortalUser.setLastName(vxUserFinal.getLastName());
-                                                               
vXPortalUser.setPassword(vxUserFinal.getPassword());
-                                                               
vXPortalUser.setUserSource(RangerCommonEnums.USER_EXTERNAL);
-                                                               
ArrayList<String> roleList = new ArrayList<String>();
-                                                               
roleList.add(RangerConstants.ROLE_USER);
-                                                               
vXPortalUser.setUserRoleList(roleList);
-                                                               ret = 
userMgr.mapVXPortalUserToXXPortalUser(vXPortalUser);
-                                ret = userMgr.createUser(ret, 
RangerCommonEnums.STATUS_ENABLED, roleList);
-                                if (logger.isDebugEnabled()) {
-                                        
logger.debug("createServiceConfigUser(): Successfully created user in 
x_portal_user table " + ret.getLoginId());
-                                }
-                            }
-                           return ret;
-                        }
-                    });
-                } catch (Exception excp) {
-                    logger.warn("createServiceConfigUser(): Failed to update 
x_portal_user table and retry count =  " + noOfRetries);
-                    xXPortalUser = null;
-                }
-            } while (noOfRetries < MAX_DB_TRANSACTION_RETRIES && (xXPortalUser 
== null));
-               }
-               VXUser createdXUser=null;
-               if (xxUser == null && vXUser != null) {
-                       try {
-                               createdXUser = 
xUserService.createResource(vXUser);
-                       } catch (Exception ex) {
-                               logger.error("Error creating user: " + 
vXUser.getName(), ex);
-                       }
-               }
-               if(createdXUser!=null){
-                       try{
-                               logger.info("User created: 
"+createdXUser.getName());
-                               createdXUser.setPassword(actualPassword);
-                               List<XXTrxLog> trxLogList = 
xUserService.getTransactionLog(createdXUser, "create");
-                               String hiddenPassword = 
PropertiesUtil.getProperty("ranger.password.hidden", "*****");
-                               createdXUser.setPassword(hiddenPassword);
-                               xaBizUtil.createTrxLog(trxLogList);
-                               if(xXPortalUser!=null){
-                                       
vXPortalUser=userMgr.mapXXPortalUserToVXPortalUserForDefaultAccount(xXPortalUser);
-                                       assignPermissionToUser(vXPortalUser, 
true);
-                               }
-                       }catch(Exception ex){
-                               logger.error("Error while assigning permissions 
to user: "+createdXUser.getName(),ex);
-                       }
-               }else{
-                       xxUser = 
daoManager.getXXUser().findByUserName(userName);
-                       if(xxUser!=null){
-                               createdXUser = 
xUserService.populateViewBean(xxUser);
-                       }
+
+               xxUser = daoManager.getXXUser().findByUserName(userName);
+               VXUser vXUser = null;
+               if (xxUser != null) {
+                       vXUser = xUserService.populateViewBean(xxUser);
                }
-               return createdXUser;
+               return vXUser;
        }
+
        protected void validatePassword(VXUser vXUser) {
                if (vXUser.getPassword() != null && 
!vXUser.getPassword().isEmpty()) {
                        boolean checkPassword = false;
@@ -3216,4 +3145,90 @@ public class XUserMgr extends XUserMgrBase {
                vXUserList = xUserService.lookupXUsers(searchCriteria, 
vXUserList);
                return vXUserList;
        }
+
+       private class ExternalUserCreator implements Runnable {
+               private String userName;
+
+               ExternalUserCreator(String user) {
+                       this.userName = user;
+               }
+
+               @Override
+               public void run() {
+                       createExternalUser();
+               }
+
+               private void createExternalUser() {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("==> 
ExternalUserCreator.createExternalUser(username=" + userName);
+                       }
+
+                       XXPortalUser xXPortalUser = 
daoManager.getXXPortalUser().findByLoginId(userName);
+                       if (xXPortalUser == null) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("createExternalUser(): 
Couldn't find " + userName+ " and hence creating user in x_portal_user table");
+                               }
+                               VXPortalUser vXPortalUser = new VXPortalUser();
+                               vXPortalUser.setLoginId(userName);
+                               
vXPortalUser.setUserSource(RangerCommonEnums.USER_EXTERNAL);
+                               ArrayList<String> roleList = new 
ArrayList<String>();
+                               roleList.add(RangerConstants.ROLE_USER);
+                               vXPortalUser.setUserRoleList(roleList);
+                               xXPortalUser = 
userMgr.mapVXPortalUserToXXPortalUser(vXPortalUser);
+                               try {
+                                       xXPortalUser = 
userMgr.createUser(xXPortalUser, RangerCommonEnums.STATUS_ENABLED, roleList);
+                                       if (logger.isDebugEnabled()) {
+                                               
logger.debug("createExternalUser(): Successfully created user in x_portal_user 
table " + xXPortalUser.getLoginId());
+                                       }
+                               } catch (Exception ex) {
+                                       throw new RuntimeException("Failed to 
create user " + userName + " in x_portal_user table. retrying", ex);
+                               }
+                       }
+
+                       VXUser createdXUser = null;
+                       String actualPassword = "";
+                       XXUser xXUser = 
daoManager.getXXUser().findByUserName(userName);
+                       if (xXPortalUser != null && xXUser == null) {
+                               VXUser vXUser = new VXUser();
+                               vXUser.setName(userName);
+                               
vXUser.setUserSource(RangerCommonEnums.USER_EXTERNAL);
+                               vXUser.setDescription(vXUser.getName());
+                               actualPassword = vXUser.getPassword();
+                               try {
+                                       createdXUser = 
xUserService.createResource(vXUser);
+                                       if (logger.isDebugEnabled()) {
+                                               
logger.debug("createExternalUser(): Successfully created user in x_user table " 
+ vXUser.getName());
+                                       }
+                               } catch (Exception ex) {
+                                       throw new RuntimeException("Failed to 
create user " + userName + " in x_user table. retrying", ex);
+                               }
+                       }
+
+                       if (createdXUser != null) {
+                               logger.info("User created: " + 
createdXUser.getName());
+                               try {
+                                       
createdXUser.setPassword(actualPassword);
+                                       List<XXTrxLog> trxLogList = 
xUserService.getTransactionLog(createdXUser, "create");
+                                       String hiddenPassword = 
PropertiesUtil.getProperty("ranger.password.hidden", "*****");
+                                       
createdXUser.setPassword(hiddenPassword);
+                                       xaBizUtil.createTrxLog(trxLogList);
+                               } catch (Exception ex) {
+                                       throw new RuntimeException("Error while 
creating trx logs for user: " + createdXUser.getName(), ex);
+                               }
+
+                               try {
+                                       if (xXPortalUser != null) {
+                                               VXPortalUser createdXPortalUser 
= userMgr.mapXXPortalUserToVXPortalUserForDefaultAccount(xXPortalUser);
+                                               
assignPermissionToUser(createdXPortalUser, true);
+                                       }
+                               } catch (Exception ex) {
+                                       throw new RuntimeException("Error while 
assigning permissions to user: " + createdXUser.getName(), ex);
+                               }
+                       }
+
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("<== 
ExternalUserCreator.createExternalUser(username=" + userName);
+                       }
+               }
+       }
 }
diff --git 
a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java 
b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
index 945bba4..bee65bb 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
@@ -37,6 +37,7 @@ import org.apache.ranger.common.RangerConstants;
 import org.apache.ranger.common.SearchCriteria;
 import org.apache.ranger.common.StringUtil;
 import org.apache.ranger.common.UserSessionBase;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
 import org.apache.ranger.db.RangerDaoManager;
 import org.apache.ranger.db.XXAuditMapDao;
 import org.apache.ranger.db.XXAuthSessionDao;
@@ -226,6 +227,10 @@ public class TestXUserMgr {
 
        @Mock
        XUgsyncAuditInfoService xUgsyncAuditInfoService;
+
+       @Mock
+       RangerTransactionSynchronizationAdapter 
transactionSynchronizationAdapter;
+
        @Rule
        public ExpectedException thrown = ExpectedException.none();
 
@@ -2108,36 +2113,40 @@ public class TestXUserMgr {
        @Test
        public void test49createServiceConfigUser() {
                XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
-               XXPortalUserDao userDao = Mockito.mock(XXPortalUserDao.class);
-               XXModuleDefDao xXModuleDefDao = 
Mockito.mock(XXModuleDefDao.class);
                VXUser vxUser = vxUser();
                XXUser xXUser = xxUser(vxUser);
                VXPortalUser userProfile = userProfile();
-               XXPortalUser xXPortalUser = xxPortalUser(userProfile);
                Collection<String> userRoleList =getRoleList();
                VXUserPermission vXUserPermission=vxUserPermission();
                XXUserPermission xUserPermissionObj = xxUserPermission();
                xUserPermissionObj.setModuleId(vXUserPermission.getModuleId());
                xUserPermissionObj.setUserId(vXUserPermission.getUserId());
-               List<XXModuleDef> xXModuleDefs = xxModuleDefs();
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
                
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(xXUser);
-               Mockito.when(daoManager.getXXPortalUser()).thenReturn(userDao);
-               
Mockito.when(userDao.findByLoginId(vxUser.getName())).thenReturn(xXPortalUser);
                
Mockito.when(xUserService.populateViewBean(xXUser)).thenReturn(vxUser);
                VXUser 
serviceConfigUser=xUserMgr.createServiceConfigUser(vxUser.getName());
                Assert.assertNotNull(serviceConfigUser);
                Assert.assertEquals(xXUser.getName(), 
serviceConfigUser.getName());
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
-               
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(null);
-               Mockito.when(daoManager.getXXPortalUser()).thenReturn(userDao);
-               
Mockito.when(userDao.findByLoginId(vxUser.getName())).thenReturn(null);
-               
Mockito.when(userDao.findByLoginId(vxUser.getName())).thenReturn(null);
-               Mockito.when(xUserService.createResource((VXUser) 
Mockito.any())).thenReturn(vxUser);
+               
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(null, 
xXUser);
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
                UserSessionBase userSession = 
Mockito.mock(UserSessionBase.class);
                Set<UserSessionBase> userSessions = new 
HashSet<UserSessionBase>();
                userSessions.add(userSession);
+
+               userProfile.setUserRoleList(userRoleList);
+               List<XXUserPermission> xUserPermissionsList = new 
ArrayList<XXUserPermission>();
+               XXUserPermission xUserPermissionObj2 = new XXUserPermission();
+               xUserPermissionObj2.setAddedByUserId(userId);
+               xUserPermissionObj2.setCreateTime(new Date());
+               xUserPermissionObj2.setId(userId);
+               xUserPermissionObj2.setIsAllowed(1);
+               xUserPermissionObj2.setModuleId(1L);
+               xUserPermissionObj2.setUpdatedByUserId(userId);
+               xUserPermissionObj2.setUpdateTime(new Date());
+               xUserPermissionObj2.setUserId(userId);
+               xUserPermissionsList.add(xUserPermissionObj2);
+
                
serviceConfigUser=xUserMgr.createServiceConfigUser(vxUser.getName());
                Assert.assertNotNull(serviceConfigUser);
                Assert.assertEquals(xXUser.getName(), 
serviceConfigUser.getName());
@@ -3306,29 +3315,20 @@ public class TestXUserMgr {
        @Test
        public void test99createServiceConfigUser() {
                XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
-               XXPortalUserDao userDao = Mockito.mock(XXPortalUserDao.class);
                VXUser vxUser = vxUser();
                XXUser xXUser = xxUser(vxUser);
-               VXPortalUser userProfile = userProfile();
-               XXPortalUser xXPortalUser = xxPortalUser(userProfile);
-               Collection<String> userRoleList =getRoleList();
                VXUserPermission vXUserPermission=vxUserPermission();
                XXUserPermission xUserPermissionObj = xxUserPermission();
                xUserPermissionObj.setModuleId(vXUserPermission.getModuleId());
                xUserPermissionObj.setUserId(vXUserPermission.getUserId());
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
                
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(xXUser);
-               Mockito.when(daoManager.getXXPortalUser()).thenReturn(userDao);
-               
Mockito.when(userDao.findByLoginId(vxUser.getName())).thenReturn(xXPortalUser);
                
Mockito.when(xUserService.populateViewBean(xXUser)).thenReturn(vxUser);
                VXUser 
serviceConfigUser=xUserMgr.createServiceConfigUser(vxUser.getName());
                Assert.assertNotNull(serviceConfigUser);
                Assert.assertEquals(xXUser.getName(), 
serviceConfigUser.getName());
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
                
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(null);
-               Mockito.when(daoManager.getXXPortalUser()).thenReturn(userDao);
-               
Mockito.when(userDao.findByLoginId(vxUser.getName())).thenReturn(null);
-               Mockito.when(xUserService.createResource((VXUser) 
Mockito.any())).thenReturn(null);
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
                UserSessionBase userSession = 
Mockito.mock(UserSessionBase.class);
                Set<UserSessionBase> userSessions = new 
HashSet<UserSessionBase>();
@@ -4624,8 +4624,6 @@ public class TestXUserMgr {
        public void test130UpdateXUser() {
                destroySession();
                setup();
-               destroySession();
-               setup();
                VXUser vxUser = vxUser();
                Mockito.when(restErrorUtil.createRESTException("Please provide 
a valid username.",MessageEnums.INVALID_INPUT_DATA)).thenThrow(new 
WebApplicationException());
                thrown.expect(WebApplicationException.class);
@@ -4646,16 +4644,30 @@ public class TestXUserMgr {
        public void test132CreateExternalUser() {
                destroySession();
                setup();
-               setup();
+               ArrayList<String> roleList = new ArrayList<String>();
+               roleList.add(RangerConstants.ROLE_USER);
+               VXPortalUser vXPortalUser = userProfile();
                XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
                VXUser vXUser = vxUser();
                VXUser createdXUser = vxUser();
+               XXUser xXUser = xxUser(vXUser);
                Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
-               
Mockito.when(xxUserDao.findByUserName(vXUser.getName())).thenReturn(null);
-               XXPortalUserDao xXPortalUserDao = 
Mockito.mock(XXPortalUserDao.class);
-               
Mockito.when(daoManager.getXXPortalUser()).thenReturn(xXPortalUserDao);
-               
Mockito.when(xXPortalUserDao.findByLoginId(vXUser.getName().trim())).thenReturn(null);
-               Mockito.when(xUserService.createResource((VXUser) 
Mockito.any())).thenReturn(createdXUser);
+               
Mockito.when(xxUserDao.findByUserName(vXUser.getName())).thenReturn(null, 
xXUser);
+               
Mockito.when(xUserService.populateViewBean(xXUser)).thenReturn(vXUser);
+
+               vXPortalUser.setUserRoleList(roleList);
+               List<XXUserPermission> xUserPermissionsList = new 
ArrayList<XXUserPermission>();
+               XXUserPermission xUserPermissionObj = new XXUserPermission();
+               xUserPermissionObj.setAddedByUserId(userId);
+               xUserPermissionObj.setCreateTime(new Date());
+               xUserPermissionObj.setId(userId);
+               xUserPermissionObj.setIsAllowed(1);
+               xUserPermissionObj.setModuleId(1L);
+               xUserPermissionObj.setUpdatedByUserId(userId);
+               xUserPermissionObj.setUpdateTime(new Date());
+               xUserPermissionObj.setUserId(userId);
+               xUserPermissionsList.add(xUserPermissionObj);
+
                createdXUser = xUserMgr.createExternalUser(vXUser.getName());
                Assert.assertNotNull(createdXUser);
                Assert.assertEquals(createdXUser.getName(), vXUser.getName());
diff --git 
a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/GroupUserInfo.java
 
b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/GroupUserInfo.java
index ffb6625..aaa0a84 100644
--- 
a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/GroupUserInfo.java
+++ 
b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/GroupUserInfo.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.ranger.ugsyncutil.model;;
+package org.apache.ranger.ugsyncutil.model;
 
 import java.util.Set;
 

Reply via email to