From c6a7d0b7727d62a6d62aeafdcb848d8c57c05eeb Mon Sep 17 00:00:00 2001 From: mposolda Date: Fri, 11 Mar 2016 12:27:37 +0100 Subject: [PATCH] KEYCLOAK-2640 LDAP group sync does not sync more than 1000 groups --- .../keycloak/federation/ldap/LDAPConfig.java | 7 +++- .../ldap/LDAPFederationProviderFactory.java | 7 ++-- .../group/GroupLDAPFederationMapper.java | 33 +++++++++++++++++-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java index 15af1332a4..eb8eaaab27 100644 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java @@ -131,7 +131,12 @@ public class LDAPConfig { public boolean isPagination() { String pagination = config.get(LDAPConstants.PAGINATION); - return pagination==null ? false : Boolean.parseBoolean(pagination); + return Boolean.parseBoolean(pagination); + } + + public int getBatchSizeForSync() { + String pageSizeConfig = config.get(LDAPConstants.BATCH_SIZE_FOR_SYNC); + return pageSizeConfig!=null ? Integer.parseInt(pageSizeConfig) : LDAPConstants.DEFAULT_BATCH_SIZE_FOR_SYNC; } public String getUsernameLdapAttribute() { diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java index bfc7fc2be9..d6dff7e5dc 100755 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java @@ -274,11 +274,10 @@ public class LDAPFederationProviderFactory extends UserFederationEventAwareProvi final UserFederationSyncResult syncResult = new UserFederationSyncResult(); - boolean pagination = Boolean.parseBoolean(fedModel.getConfig().get(LDAPConstants.PAGINATION)); + LDAPConfig ldapConfig = new LDAPConfig(fedModel.getConfig()); + boolean pagination = ldapConfig.isPagination(); if (pagination) { - - String pageSizeConfig = fedModel.getConfig().get(LDAPConstants.BATCH_SIZE_FOR_SYNC); - int pageSize = pageSizeConfig!=null ? Integer.parseInt(pageSizeConfig) : LDAPConstants.DEFAULT_BATCH_SIZE_FOR_SYNC; + int pageSize = ldapConfig.getBatchSizeForSync(); boolean nextPage = true; while (nextPage) { diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapper.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapper.java index 2c1c048c08..a5ad49e80a 100644 --- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapper.java +++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/membership/group/GroupLDAPFederationMapper.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Set; import org.jboss.logging.Logger; +import org.keycloak.federation.ldap.LDAPConfig; import org.keycloak.federation.ldap.LDAPFederationProvider; import org.keycloak.federation.ldap.LDAPUtils; import org.keycloak.federation.ldap.idm.model.LDAPDn; @@ -41,9 +42,11 @@ import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode; import org.keycloak.federation.ldap.mappers.membership.MembershipType; import org.keycloak.federation.ldap.mappers.membership.UserRolesRetrieveStrategy; import org.keycloak.models.GroupModel; +import org.keycloak.models.LDAPConstants; import org.keycloak.models.ModelException; import org.keycloak.models.RealmModel; import org.keycloak.models.UserFederationMapperModel; +import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; @@ -149,8 +152,7 @@ public class GroupLDAPFederationMapper extends AbstractLDAPFederationMapper impl logger.debugf("Syncing groups from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName()); // Get all LDAP groups - LDAPQuery ldapQuery = createGroupQuery(); - List ldapGroups = ldapQuery.getResultList(); + List ldapGroups = getAllLDAPGroups(); // Convert to internal format Map ldapGroupsMap = new HashMap<>(); @@ -321,6 +323,33 @@ public class GroupLDAPFederationMapper extends AbstractLDAPFederationMapper impl return kcGroup; } + // Send LDAP query to retrieve all groups + protected List getAllLDAPGroups() { + LDAPQuery ldapGroupQuery = createGroupQuery(); + + LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig(); + boolean pagination = ldapConfig.isPagination(); + if (pagination) { + // For now reuse globally configured batch size in LDAP provider page + int pageSize = ldapConfig.getBatchSizeForSync(); + + List result = new LinkedList<>(); + boolean nextPage = true; + + while (nextPage) { + ldapGroupQuery.setLimit(pageSize); + final List currentPageGroups = ldapGroupQuery.getResultList(); + result.addAll(currentPageGroups); + nextPage = ldapGroupQuery.getPaginationContext() != null; + } + + return result; + } else { + // LDAP pagination not available. Do everything in single transaction + return ldapGroupQuery.getResultList(); + } + } + // Sync from Keycloak to LDAP