keycloak-uncached
Changes
misc/Testsuite.md 57(+56 -1)
testsuite/integration/pom.xml 10(+0 -10)
Details
misc/Testsuite.md 57(+56 -1)
diff --git a/misc/Testsuite.md b/misc/Testsuite.md
index 41a578c..9b99036 100644
--- a/misc/Testsuite.md
+++ b/misc/Testsuite.md
@@ -143,6 +143,61 @@ kinit hnelson@KEYCLOAK.ORG
and provide password `secret`
-Now when you access `http://localhost:8081/auth/realms/master/account` you should be logged in automatically as user `hnelson` .
+Now when you access `http://localhost:8081/auth/realms/master/account` you should be logged in automatically as user `hnelson` .
+
+
+Create many users or offline sessions
+-------------------------------------
+Run testsuite with the command like this:
+
+```
+mvn exec:java -Pkeycloak-server -DstartTestsuiteCLI
+```
+
+Alternatively if you want to use your MySQL database use the command like this (replace properties values according your DB connection):
+
+```
+mvn exec:java -Pkeycloak-server -Dkeycloak.connectionsJpa.url=jdbc:mysql://localhost/keycloak -Dkeycloak.connectionsJpa.driver=com.mysql.jdbc.Driver -Dkeycloak.connectionsJpa.user=keycloak -Dkeycloak.connectionsJpa.password=keycloak -DstartTestsuiteCLI
+```
+
+Then once CLI is started, you can use command `help` to see all the available commands.
+
+### Creating many users
+
+For create many users you can use command `createUsers`
+For example this will create 500 users `test0, test1, test2, ... , test499` in realm `demo` and each 100 users in separate transaction. All users will be granted realm roles `user` and `admin` :
+
+```
+createUsers test test demo 0 500 100 user,admin
+```
+
+Check count of users:
+
+```
+getUsersCount demo
+```
+
+Check if concrete user was really created:
+
+```
+getUser demo test499
+```
+
+### Creating many offline sessions
+
+For create many offline sessions you can use command `persistSessions` . For example create 50000 sessions (each 500 in separate transaction) with command:
+
+```
+persistSessions 50000 500
+```
+
+Once users or sessions are created, you can restart to ensure the startup import of offline sessions will be triggered and you can see impact on startup time. After restart you can use command:
+
+```
+size
+```
+
+to doublecheck total count of sessions in infinispan (it will be 2 times as there is also 1 client session per each user session created)
+
diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml
index 11fd15e..5b3b2b4 100755
--- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml
+++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml
@@ -73,5 +73,9 @@
<dropUniqueConstraint tableName="FED_PROVIDERS" constraintName="UK_DCCIRJLIPU1478VQC89DID88C" />
<dropTable tableName="FED_PROVIDERS" />
+ <createIndex indexName="IDX_US_SESS_ID_ON_CL_SESS" tableName="OFFLINE_CLIENT_SESSION">
+ <column name="USER_SESSION_ID" type="VARCHAR(36)"/>
+ </createIndex>
+
</changeSet>
</databaseChangeLog>
\ No newline at end of file
testsuite/integration/pom.xml 10(+0 -10)
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index 3672b3d..8dafd44 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -237,16 +237,6 @@
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
- <dependency>
- <groupId>org.postgresql</groupId>
- <artifactId>postgresql</artifactId>
- <version>${postgresql.version}</version>
- </dependency>
-
</dependencies>
<build>
<plugins>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
index 30a3947..6cb3f7c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
@@ -33,7 +33,7 @@ import org.keycloak.services.filters.KeycloakSessionServletFilter;
import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
-import org.keycloak.testsuite.util.cli.InfinispanCLI;
+import org.keycloak.testsuite.util.cli.TestsuiteCLI;
import org.keycloak.util.JsonSerialization;
import javax.servlet.DispatcherType;
@@ -206,8 +206,8 @@ public class KeycloakServer {
}
});
- if (System.getProperties().containsKey("startInfinispanCLI")) {
- new InfinispanCLI(keycloak).start();
+ if (System.getProperties().containsKey("startTestsuiteCLI")) {
+ new TestsuiteCLI(keycloak).start();
}
return keycloak;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java
index 8b72c1d..0b6d228 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java
@@ -35,7 +35,7 @@ public abstract class AbstractCommand {
protected List<String> args;
protected KeycloakSessionFactory sessionFactory;
- public void injectProperties(List<String> args, InfinispanCLI cli, KeycloakSessionFactory sessionFactory) {
+ public void injectProperties(List<String> args, TestsuiteCLI cli, KeycloakSessionFactory sessionFactory) {
this.args = args;
this.sessionFactory = sessionFactory;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java
index 7f67865..bec0487 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java
@@ -43,10 +43,32 @@ public class PersistSessionsCommand extends AbstractCommand {
@Override
public void doRunCommand(KeycloakSession sess) {
final int count = getIntArg(0);
+ final int batchCount = getIntArg(1);
+
+ int remaining = count;
+
+ while (remaining > 0) {
+ int createInThisBatch = Math.min(batchCount, remaining);
+ createSessionsBatch(createInThisBatch);
+ remaining = remaining - createInThisBatch;
+ }
+
+ // Write some summary
+ KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+
+ @Override
+ public void run(KeycloakSession session) {
+ UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
+ log.info("Command finished. Total number of sessions in persister: " + persister.getUserSessionsCount(true));
+ }
+
+ });
+ }
+
+ private void createSessionsBatch(final int countInThisBatch) {
final List<String> userSessionIds = new LinkedList<>();
final List<String> clientSessionIds = new LinkedList<>();
- // Create sessions in separate transaction first
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
@Override
@@ -56,7 +78,7 @@ public class PersistSessionsCommand extends AbstractCommand {
ClientModel testApp = realm.getClientByClientId("security-admin-console");
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < countInThisBatch; i++) {
UserSessionModel userSession = session.sessions().createUserSession(realm, john, "john-doh@localhost", "127.0.0.2", "form", true, null, null);
ClientSessionModel clientSession = session.sessions().createClientSession(realm, testApp);
clientSession.setUserSession(userSession);
@@ -69,9 +91,10 @@ public class PersistSessionsCommand extends AbstractCommand {
});
- log.info("Sessions created in infinispan storage");
+ log.infof("%d sessions created in infinispan storage", countInThisBatch);
// Persist them now
+
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
@Override
@@ -84,35 +107,17 @@ public class PersistSessionsCommand extends AbstractCommand {
counter++;
UserSessionModel userSession = session.sessions().getUserSession(realm, userSessionId);
persister.createUserSession(userSession, true);
- if (counter%1000 == 0) {
- log.infof("%d user sessions persisted. Continue", counter);
- }
}
- log.infof("All %d user sessions persisted", counter);
+ log.infof("%d user sessions persisted. Continue", counter);
counter = 0;
for (String clientSessionId : clientSessionIds) {
counter++;
ClientSessionModel clientSession = session.sessions().getClientSession(realm, clientSessionId);
persister.createClientSession(clientSession, true);
- if (counter%1000 == 0) {
- log.infof("%d client sessions persisted. Continue", counter);
- }
}
-
- log.infof("All %d client sessions persisted", counter);
- }
-
- });
-
- // Persist them now
- KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
-
- @Override
- public void run(KeycloakSession session) {
- UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
- log.info("Total number of sessions in persister: " + persister.getUserSessionsCount(true));
+ log.infof("%d client sessions persisted. Continue", counter);
}
});
@@ -120,6 +125,6 @@ public class PersistSessionsCommand extends AbstractCommand {
@Override
public String printUsage() {
- return super.printUsage() + " <sessions-count>";
+ return super.printUsage() + " <sessions-count> <sessions-count-per-each-transaction>";
}
}