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;
|
||||
|
||||
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.LifeCycle;
|
||||
import org.keycloak.test.framework.injection.Registry;
|
||||
import org.keycloak.test.framework.injection.Supplier;
|
||||
import org.keycloak.test.framework.injection.SupplierHelpers;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractKeycloakTestServerSupplier implements Supplier<KeycloakTestServer, KeycloakIntegrationTest> {
|
||||
|
||||
@Override
|
||||
|
@ -22,12 +26,22 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
|||
@Override
|
||||
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
|
||||
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.start(serverConfig, databaseConfig);
|
||||
|
||||
keycloakTestServer.start(serverConfig);
|
||||
wrapper.setValue(keycloakTestServer, LifeCycle.GLOBAL);
|
||||
|
||||
return new InstanceWrapper<>(this, annotation, keycloakTestServer, LifeCycle.GLOBAL);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,4 +56,6 @@ public abstract class AbstractKeycloakTestServerSupplier implements Supplier<Key
|
|||
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
||||
|
||||
|
@ -16,7 +17,7 @@ public class DistributionKeycloakTestServer implements KeycloakTestServer {
|
|||
private RawKeycloakDistribution keycloak;
|
||||
|
||||
@Override
|
||||
public void start(KeycloakTestServerConfig serverConfig) {
|
||||
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||
keycloak = new RawKeycloakDistribution(debug, manualStop, enableTls, reCreate, removeBuildOptionsAfterBuild, requestPort);
|
||||
|
||||
// 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));
|
||||
|
||||
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||
|
||||
keycloak.run(rawOptions).assertStartedDevMode();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,4 +7,9 @@ public class DistributionKeycloakTestServerSupplier extends AbstractKeycloakTest
|
|||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
||||
|
@ -12,20 +13,20 @@ public class EmbeddedKeycloakTestServer implements KeycloakTestServer {
|
|||
private Keycloak keycloak;
|
||||
|
||||
@Override
|
||||
public void start(KeycloakTestServerConfig serverConfig) {
|
||||
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||
List<String> rawOptions = new LinkedList<>();
|
||||
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");
|
||||
|
||||
if (!serverConfig.features().isEmpty()) {
|
||||
rawOptions.add("--features=" + String.join(",", serverConfig.features()));
|
||||
}
|
||||
|
||||
serverConfig.adminUserName().ifPresent(username -> rawOptions.add("--bootstrap-admin-username=" + username));
|
||||
serverConfig.adminUserPassword().ifPresent(password -> rawOptions.add("--bootstrap-admin-password=" + password));
|
||||
|
||||
serverConfig.adminUserName().ifPresent(username -> System.setProperty("keycloakAdmin", username));
|
||||
serverConfig.adminUserPassword().ifPresent(password -> System.setProperty("keycloakAdminPassword", password));
|
||||
|
||||
serverConfig.options().forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||
databaseConfig.forEach((key, value) -> rawOptions.add("--" + key + "=" + value));
|
||||
|
||||
keycloak = Keycloak.builder()
|
||||
.setVersion(Version.VERSION)
|
||||
|
|
|
@ -7,4 +7,9 @@ public class EmbeddedKeycloakTestServerSupplier extends AbstractKeycloakTestServ
|
|||
return new EmbeddedKeycloakTestServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresDatabase() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package org.keycloak.test.framework.server;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface KeycloakTestServer {
|
||||
|
||||
void start(KeycloakTestServerConfig serverConfig);
|
||||
void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig);
|
||||
|
||||
void stop();
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package org.keycloak.test.framework.server;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RemoteKeycloakTestServer implements KeycloakTestServer {
|
||||
|
||||
@Override
|
||||
public void start(KeycloakTestServerConfig serverConfig) {
|
||||
|
||||
public void start(KeycloakTestServerConfig serverConfig, Map<String, String> databaseConfig) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,4 +7,9 @@ public class RemoteKeycloakTestServerSupplier extends AbstractKeycloakTestServer
|
|||
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.webdriver.ChromeWebDriverSupplier
|
||||
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