Merge pull request #533 from mposolda/master
Added method UserProvider.getUsersCount(). Refactor export-import witth users pagination
This commit is contained in:
commit
9abe357754
11 changed files with 64 additions and 30 deletions
|
@ -304,8 +304,10 @@ public class MongoStoreImpl implements MongoStore {
|
|||
context.beforeDBSearch(type);
|
||||
|
||||
DBCollection dbCollection = getDBCollectionForType(type);
|
||||
DBCursor cursor = dbCollection.find(query);
|
||||
return cursor.size();
|
||||
Long count = dbCollection.count(query);
|
||||
|
||||
// For now, assume that int is sufficient
|
||||
return count.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,8 +56,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
|||
|
||||
// Count total number of users
|
||||
if (!exportUsersIntoSameFile) {
|
||||
// TODO: getUsersCount method on model
|
||||
usersHolder.totalCount = session.users().getUsers(realm).size();
|
||||
usersHolder.totalCount = session.users().getUsersCount(realm);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,13 +81,11 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
|||
@Override
|
||||
public void run(KeycloakSession session) throws IOException {
|
||||
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||
// TODO: pagination
|
||||
List<UserModel> users = session.users().getUsers(realm);
|
||||
usersHolder.users = users.subList(usersHolder.currentPageStart, usersHolder.currentPageEnd);
|
||||
usersHolder.users = session.users().getUsers(realm, usersHolder.currentPageStart, usersHolder.currentPageEnd - usersHolder.currentPageStart);
|
||||
|
||||
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
|
||||
|
||||
logger.info("Users " + usersHolder.currentPageStart + "-" + usersHolder.currentPageEnd + " exported");
|
||||
logger.info("Users " + usersHolder.currentPageStart + "-" + (usersHolder.currentPageEnd -1) + " exported");
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@ public interface UserProvider extends Provider {
|
|||
UserModel getUserByEmail(String email, RealmModel realm);
|
||||
UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm);
|
||||
List<UserModel> getUsers(RealmModel realm);
|
||||
int getUsersCount(RealmModel realm);
|
||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
|
||||
List<UserModel> searchForUser(String search, RealmModel realm);
|
||||
List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults);
|
||||
|
|
|
@ -184,6 +184,11 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
|||
return getDelegate().getUsers(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsersCount(RealmModel realm) {
|
||||
return getDelegate().getUsersCount(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
return getDelegate().getUsers(realm, firstResult, maxResults);
|
||||
|
|
|
@ -66,6 +66,11 @@ public class NoCacheUserProvider implements CacheUserProvider {
|
|||
return getDelegate().getUsers(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsersCount(RealmModel realm) {
|
||||
return getDelegate().getUsersCount(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
return getDelegate().getUsers(realm, firstResult, maxResults);
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.keycloak.models.utils.CredentialValidation;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
@ -205,6 +206,17 @@ public class JpaUserProvider implements UserProvider {
|
|||
return getUsers(realm, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsersCount(RealmModel realm) {
|
||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
||||
|
||||
// TODO: named query?
|
||||
Object count = em.createQuery("select count(u) from UserEntity u where u.realm = :realm")
|
||||
.setParameter("realm", realmEntity)
|
||||
.getSingleResult();
|
||||
return ((Number)count).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm order by u.username", UserEntity.class);
|
||||
|
|
|
@ -116,6 +116,14 @@ public class MongoUserProvider implements UserProvider {
|
|||
return getUsers(realm, -1, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsersCount(RealmModel realm) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("realmId").is(realm.getId())
|
||||
.get();
|
||||
return getMongoStore().countEntities(MongoUserEntity.class, query, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
DBObject query = new QueryBuilder()
|
||||
|
|
|
@ -479,17 +479,17 @@
|
|||
<id>mongo</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>keycloak.model.provider</name>
|
||||
<name>keycloak.realm.provider</name>
|
||||
<value>mongo</value>
|
||||
</property>
|
||||
</activation>
|
||||
|
||||
<properties>
|
||||
<keycloak.model.mongo.host>localhost</keycloak.model.mongo.host>
|
||||
<keycloak.model.mongo.port>27018</keycloak.model.mongo.port>
|
||||
<keycloak.model.mongo.db>keycloak</keycloak.model.mongo.db>
|
||||
<keycloak.model.mongo.clearOnStartup>true</keycloak.model.mongo.clearOnStartup>
|
||||
<keycloak.model.mongo.bindIp>127.0.0.1</keycloak.model.mongo.bindIp>
|
||||
<keycloak.connectionsMongo.host>localhost</keycloak.connectionsMongo.host>
|
||||
<keycloak.connectionsMongo.port>27018</keycloak.connectionsMongo.port>
|
||||
<keycloak.connectionsMongo.db>keycloak</keycloak.connectionsMongo.db>
|
||||
<keycloak.connectionsMongo.clearOnStartup>true</keycloak.connectionsMongo.clearOnStartup>
|
||||
<keycloak.connectionsMongo.bindIp>127.0.0.1</keycloak.connectionsMongo.bindIp>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -508,12 +508,15 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<keycloak.model.provider>mongo</keycloak.model.provider>
|
||||
<keycloak.model.mongo.host>${keycloak.model.mongo.host}</keycloak.model.mongo.host>
|
||||
<keycloak.model.mongo.port>${keycloak.model.mongo.port}</keycloak.model.mongo.port>
|
||||
<keycloak.model.mongo.db>${keycloak.model.mongo.db}</keycloak.model.mongo.db>
|
||||
<keycloak.model.mongo.clearOnStartup>${keycloak.model.mongo.clearOnStartup}</keycloak.model.mongo.clearOnStartup>
|
||||
<keycloak.model.mongo.bindIp>${keycloak.model.mongo.bindIp}</keycloak.model.mongo.bindIp>
|
||||
<keycloak.realm.provider>mongo</keycloak.realm.provider>
|
||||
<keycloak.user.provider>mongo</keycloak.user.provider>
|
||||
<keycloak.audit.provider>mongo</keycloak.audit.provider>
|
||||
<!--<keycloak.userSessions.provider>mongo</keycloak.userSessions.provider>-->
|
||||
<keycloak.connectionsMongo.host>${keycloak.connectionsMongo.host}</keycloak.connectionsMongo.host>
|
||||
<keycloak.connectionsMongo.port>${keycloak.connectionsMongo.port}</keycloak.connectionsMongo.port>
|
||||
<keycloak.connectionsMongo.db>${keycloak.connectionsMongo.db}</keycloak.connectionsMongo.db>
|
||||
<keycloak.connectionsMongo.clearOnStartup>${keycloak.connectionsMongo.clearOnStartup}</keycloak.connectionsMongo.clearOnStartup>
|
||||
<keycloak.connectionsMongo.bindIp>${keycloak.connectionsMongo.bindIp}</keycloak.connectionsMongo.bindIp>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
@ -538,10 +541,10 @@
|
|||
<goal>start</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<port>${keycloak.model.mongo.port}</port>
|
||||
<port>${keycloak.connectionsMongo.port}</port>
|
||||
<logging>file</logging>
|
||||
<logFile>${project.build.directory}/mongodb.log</logFile>
|
||||
<bindIp>${keycloak.model.mongo.bindIp}</bindIp>
|
||||
<bindIp>${keycloak.connectionsMongo.bindIp}</bindIp>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
},
|
||||
|
||||
"audit": {
|
||||
"provider": "${keycloak.audit.provider,keycloak.model.provider:jpa}"
|
||||
"provider": "${keycloak.audit.provider:jpa}"
|
||||
},
|
||||
|
||||
"realm": {
|
||||
|
@ -58,10 +58,10 @@
|
|||
|
||||
"connectionsMongo": {
|
||||
"default": {
|
||||
"host": "${keycloak.model.mongo.host:127.0.0.1}",
|
||||
"port": "${keycloak.model.mongo.port:27017}",
|
||||
"db": "${keycloak.model.mongo.db:keycloak}",
|
||||
"clearOnStartup": "${keycloak.model.mongo.clearOnStartup:false}"
|
||||
"host": "${keycloak.connectionsMongo.host:127.0.0.1}",
|
||||
"port": "${keycloak.connectionsMongo.port:27017}",
|
||||
"db": "${keycloak.connectionsMongo.db:keycloak}",
|
||||
"clearOnStartup": "${keycloak.connectionsMongo.clearOnStartup:false}"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class ExportImportTest {
|
|||
// We want data to be persisted among server restarts
|
||||
private static ExternalResource mongoRule = new ExternalResource() {
|
||||
|
||||
private static final String MONGO_CLEAR_ON_STARTUP_PROP_NAME = "keycloak.model.mongo.clearOnStartup";
|
||||
private static final String MONGO_CLEAR_ON_STARTUP_PROP_NAME = "keycloak.connectionsMongo.clearOnStartup";
|
||||
private String previousMongoClearOnStartup;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -163,8 +163,9 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
new Socket(server.getConfig().getHost(), server.getConfig().getPort());
|
||||
throw new RuntimeException();
|
||||
Socket s = new Socket(server.getConfig().getHost(), server.getConfig().getPort());
|
||||
s.close();
|
||||
throw new IllegalStateException("Server still running");
|
||||
} catch (IOException expected) {
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue