You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by pr...@apache.org on 2022/01/12 03:30:30 UTC
[ranger] branch master updated: RANGER-3576: service creation is failing intermittently due to DB unique key constraint violation
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 <pr...@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;