Adding database suppliers (#31073)
* Closes #30616. Added database suppliers. Signed-off-by: Miquel Simon <msimonma@redhat.com> Co-authored-by: stianst <stianst@gmail.com>
This commit is contained in:
parent
2140e573f2
commit
73247f585a
16 changed files with 250 additions and 12 deletions
|
@ -0,0 +1,19 @@
|
||||||
|
package org.keycloak.test.framework;
|
||||||
|
|
||||||
|
import org.keycloak.test.framework.database.DatabaseConfig;
|
||||||
|
import org.keycloak.test.framework.injection.LifeCycle;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface KeycloakTestDatabase {
|
||||||
|
|
||||||
|
Class<? extends DatabaseConfig> config() default DatabaseConfig.class;
|
||||||
|
|
||||||
|
LifeCycle lifecycle() default LifeCycle.GLOBAL;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
import org.keycloak.test.framework.KeycloakTestDatabase;
|
||||||
|
import org.keycloak.test.framework.injection.InstanceWrapper;
|
||||||
|
import org.keycloak.test.framework.injection.LifeCycle;
|
||||||
|
import org.keycloak.test.framework.injection.Registry;
|
||||||
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
|
|
||||||
|
public abstract class AbstractDatabaseSupplier implements Supplier<TestDatabase, KeycloakTestDatabase> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<KeycloakTestDatabase> getAnnotationClass() {
|
||||||
|
return KeycloakTestDatabase.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<TestDatabase> getValueType() {
|
||||||
|
return TestDatabase.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InstanceWrapper<TestDatabase, KeycloakTestDatabase> getValue(Registry registry, KeycloakTestDatabase annotation) {
|
||||||
|
TestDatabase testDatabase = getTestDatabase();
|
||||||
|
testDatabase.start();
|
||||||
|
return new InstanceWrapper<>(this, annotation, testDatabase, LifeCycle.GLOBAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean compatible(InstanceWrapper<TestDatabase, KeycloakTestDatabase> a, InstanceWrapper<TestDatabase, KeycloakTestDatabase> b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract TestDatabase getTestDatabase();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DatabaseConfig {
|
||||||
|
|
||||||
|
private String vendor;
|
||||||
|
private String containerImage;
|
||||||
|
private String urlHost;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public String getVendor() {
|
||||||
|
return vendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConfig vendor(String vendor) {
|
||||||
|
this.vendor = vendor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContainerImage() {
|
||||||
|
return containerImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConfig containerImage(String containerImage) {
|
||||||
|
this.containerImage = containerImage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrlHost() {
|
||||||
|
return urlHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConfig urlHost(String urlHost) {
|
||||||
|
this.urlHost = urlHost;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConfig username(String username) {
|
||||||
|
this.username = username;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConfig password(String password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> toConfig() {
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
if (vendor != null) {
|
||||||
|
config.put("db", vendor);
|
||||||
|
}
|
||||||
|
if (urlHost != null) {
|
||||||
|
config.put("db-url-host", urlHost);
|
||||||
|
}
|
||||||
|
if (username != null) {
|
||||||
|
config.put("db-username", username);
|
||||||
|
}
|
||||||
|
if (password != null) {
|
||||||
|
config.put("db-password", password);
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
public class DevFileDatabaseSupplier extends AbstractDatabaseSupplier {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
TestDatabase getTestDatabase() {
|
||||||
|
DatabaseConfig databaseConfig = new DatabaseConfig().vendor("dev-file");
|
||||||
|
return new TestDatabase(databaseConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
public class DevMemDatabaseSupplier extends AbstractDatabaseSupplier {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
TestDatabase getTestDatabase() {
|
||||||
|
DatabaseConfig databaseConfig = new DatabaseConfig().vendor("dev-mem");
|
||||||
|
return new TestDatabase(databaseConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
public class PostgresDatabaseSupplier extends AbstractDatabaseSupplier {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
TestDatabase getTestDatabase() {
|
||||||
|
DatabaseConfig databaseConfig = new DatabaseConfig()
|
||||||
|
.vendor("postgres")
|
||||||
|
.username("keycloak")
|
||||||
|
.password("keycloak")
|
||||||
|
.containerImage("the-postgres-container:the-version");
|
||||||
|
return new TestDatabase(databaseConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.keycloak.test.framework.database;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TestDatabase {
|
||||||
|
|
||||||
|
private DatabaseConfig databaseConfig;
|
||||||
|
|
||||||
|
public TestDatabase(DatabaseConfig databaseConfig) {
|
||||||
|
this.databaseConfig = databaseConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (databaseConfig.getContainerImage() != null) {
|
||||||
|
// TODO Start container
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (databaseConfig.getContainerImage() != null) {
|
||||||
|
// TODO Stop container
|
||||||
|
} else if (databaseConfig.getVendor().equals("dev-mem")) {
|
||||||
|
// TODO Stop in-mem H2 database
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getServerConfig() {
|
||||||
|
return databaseConfig.toConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +1,16 @@
|
||||||
package org.keycloak.test.framework.server;
|
package org.keycloak.test.framework.server;
|
||||||
|
|
||||||
import org.keycloak.test.framework.KeycloakIntegrationTest;
|
import org.keycloak.test.framework.KeycloakIntegrationTest;
|
||||||
|
import org.keycloak.test.framework.database.TestDatabase;
|
||||||
import org.keycloak.test.framework.injection.InstanceWrapper;
|
import org.keycloak.test.framework.injection.InstanceWrapper;
|
||||||
import org.keycloak.test.framework.injection.LifeCycle;
|
import org.keycloak.test.framework.injection.LifeCycle;
|
||||||
import org.keycloak.test.framework.injection.Registry;
|
import org.keycloak.test.framework.injection.Registry;
|
||||||
import org.keycloak.test.framework.injection.Supplier;
|
import org.keycloak.test.framework.injection.Supplier;
|
||||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class AbstractKeycloakTestServerSupplier implements Supplier<KeycloakTestServer, KeycloakIntegrationTest> {
|
public abstract class AbstractKeycloakTestServerSupplier implements Supplier<KeycloakTestServer, KeycloakIntegrationTest> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,12 +26,22 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
||||||
@Override
|
@Override
|
||||||
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
|
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
|
||||||
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
|
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
|
||||||
|
InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> wrapper = new InstanceWrapper<>(this, annotation);
|
||||||
|
|
||||||
|
Map<String, String> databaseConfig;
|
||||||
|
if (requiresDatabase()) {
|
||||||
|
TestDatabase testDatabase = registry.getDependency(TestDatabase.class, wrapper);
|
||||||
|
databaseConfig = testDatabase.getServerConfig();
|
||||||
|
} else {
|
||||||
|
databaseConfig = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
KeycloakTestServer keycloakTestServer = getServer();
|
KeycloakTestServer keycloakTestServer = getServer();
|
||||||
|
keycloakTestServer.start(serverConfig, databaseConfig);
|
||||||
|
|
||||||
keycloakTestServer.start(serverConfig);
|
wrapper.setValue(keycloakTestServer, LifeCycle.GLOBAL);
|
||||||
|
|
||||||
return new InstanceWrapper<>(this, annotation, keycloakTestServer, LifeCycle.GLOBAL);
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,4 +56,6 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
||||||
|
|
||||||
public abstract KeycloakTestServer getServer();
|
public abstract KeycloakTestServer getServer();
|
||||||
|
|
||||||
|
public abstract boolean requiresDatabase();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.keycloak.it.utils.RawKeycloakDistribution;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
||||||
private RawKeycloakDistribution keycloak;
|
private RawKeycloakDistribution keycloak;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(KeycloakTestServerConfig serverConfig) {
|
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||||
keycloak = new RawKeycloakDistribution(debug, manualStop, enableTls, reCreate, removeBuildOptionsAfterBuild, requestPort);
|
keycloak = new RawKeycloakDistribution(debug, manualStop, enableTls, reCreate, removeBuildOptionsAfterBuild, requestPort);
|
||||||
|
|
||||||
// Set environment variables user and password for Keycloak Admin used by Keycloak instance.
|
// Set environment variables user and password for Keycloak Admin used by Keycloak instance.
|
||||||
|
@ -35,6 +36,8 @@ public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
||||||
|
|
||||||
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
|
|
||||||
|
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
|
|
||||||
keycloak.run(rawOptions).assertStartedDevMode();
|
keycloak.run(rawOptions).assertStartedDevMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,9 @@ public class DistributionKeycloakTestServerSupplier extends AbstractKeycloakTest
|
||||||
return new DistributionKeycloakTestServer();
|
return new DistributionKeycloakTestServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresDatabase() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.keycloak.common.Version;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
||||||
|
@ -12,20 +13,20 @@ public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
||||||
private Keycloak keycloak;
|
private Keycloak keycloak;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(KeycloakTestServerConfig serverConfig) {
|
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||||
List<String> rawOptions = new LinkedList<>();
|
List<String> rawOptions = new LinkedList<>();
|
||||||
rawOptions.add("start-dev");
|
rawOptions.add("start-dev");
|
||||||
// rawOptions.add("--db=dev-mem"); // TODO With dev-mem there's an issue as the H2 DB isn't stopped when restarting embedded server
|
|
||||||
rawOptions.add("--cache=local");
|
rawOptions.add("--cache=local");
|
||||||
|
|
||||||
if (!serverConfig.features().isEmpty()) {
|
if (!serverConfig.features().isEmpty()) {
|
||||||
rawOptions.add("--features=" + String.join(",", serverConfig.features()));
|
rawOptions.add("--features=" + String.join(",", serverConfig.features()));
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig.adminUserName().ifPresent(username -> rawOptions.add("--bootstrap-admin-username=" + username));
|
serverConfig.adminUserName().ifPresent(username -> System.setProperty("keycloakAdmin", username));
|
||||||
serverConfig.adminUserPassword().ifPresent(password -> rawOptions.add("--bootstrap-admin-password=" + password));
|
serverConfig.adminUserPassword().ifPresent(password -> System.setProperty("keycloakAdminPassword", password));
|
||||||
|
|
||||||
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
|
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||||
|
|
||||||
keycloak = Keycloak.builder()
|
keycloak = Keycloak.builder()
|
||||||
.setVersion(Version.VERSION)
|
.setVersion(Version.VERSION)
|
||||||
|
|
|
@ -7,4 +7,9 @@ public class EmbeddedKeycloakTestServerSupplier extends AbstractKeycloakTestServ
|
||||||
return new EmbeddedKeycloakTestServer();
|
return new EmbeddedKeycloakTestServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresDatabase() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package org.keycloak.test.framework.server;
|
package org.keycloak.test.framework.server;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface KeycloakTestServer {
|
public interface KeycloakTestServer {
|
||||||
|
|
||||||
void start(KeycloakTestServerConfig serverConfig);
|
void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package org.keycloak.test.framework.server;
|
package org.keycloak.test.framework.server;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class RemoteKeycloakTestServer implements KeycloakTestServer {
|
public class RemoteKeycloakTestServer implements KeycloakTestServer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(KeycloakTestServerConfig serverConfig) {
|
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,4 +7,9 @@ public class RemoteKeycloakTestServerSupplier extends AbstractKeycloakTestServer
|
||||||
return new RemoteKeycloakTestServer();
|
return new RemoteKeycloakTestServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresDatabase() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,3 +7,6 @@ org.keycloak.test.framework.server.DistributionKeycloakTestServerSupplier
|
||||||
org.keycloak.test.framework.server.RemoteKeycloakTestServerSupplier
|
org.keycloak.test.framework.server.RemoteKeycloakTestServerSupplier
|
||||||
org.keycloak.test.framework.webdriver.ChromeWebDriverSupplier
|
org.keycloak.test.framework.webdriver.ChromeWebDriverSupplier
|
||||||
org.keycloak.test.framework.webdriver.FirefoxWebDriverSupplier
|
org.keycloak.test.framework.webdriver.FirefoxWebDriverSupplier
|
||||||
|
org.keycloak.test.framework.database.DevMemDatabaseSupplier
|
||||||
|
org.keycloak.test.framework.database.DevFileDatabaseSupplier
|
||||||
|
org.keycloak.test.framework.database.PostgresDatabaseSupplier
|
Loading…
Reference in a new issue