diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml index 3237efe6a4..475d84da41 100644 --- a/testsuite/integration-arquillian/pom.xml +++ b/testsuite/integration-arquillian/pom.xml @@ -442,11 +442,17 @@ db-mysql + mysql com.mysql.jdbc.Driver keycloak keycloak keycloak jdbc:mysql://${auth.server.db.host}/${keycloak.connectionsJpa.database}?allowPublicKeyRetrieval=true + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} + @@ -470,11 +476,16 @@ db-postgres + postgres org.postgresql.Driver keycloak keycloak keycloak jdbc:postgresql://${auth.server.db.host}/${keycloak.connectionsJpa.database} + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} @@ -505,11 +516,16 @@ db-mariadb + mariadb org.mariadb.jdbc.Driver keycloak keycloak keycloak jdbc:mariadb://${auth.server.db.host}/${keycloak.connectionsJpa.database} + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} @@ -540,11 +556,16 @@ /opt/mssql-tools/bin/sqlcmd -e -U sa -P vEry5tron9Pwd -d master -Q CREATE\ DATABASE\ ${keycloak.connectionsJpa.database} /bin/sh -c /opt/mssql/bin/sqlservr (?si)SQL Server is now ready for client connections.*Service Broker manager has started + mssql com.microsoft.sqlserver.jdbc.SQLServerDriver keycloak sa vEry5tron9Pwd jdbc:sqlserver://${auth.server.db.host}:${docker.database.port};databaseName=${keycloak.connectionsJpa.database} + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} @@ -569,11 +590,17 @@ false /bin/sh -c exec\ $ORACLE_BASE/$RUN_FILE (?si)DATABASE IS READY TO USE + oracle oracle.jdbc.OracleDriver XE keycloak keycloak jdbc:oracle:thin:@${auth.server.db.host}:${docker.database.port}:${keycloak.connectionsJpa.database} + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} + bash -c while\ !\ sqlplus\ -L\ SYS/sa@localhost/XE\ AS\ SYSDBA\ <<<\ $'CREATE\ USER\ ${keycloak.connectionsJpa.user}\ IDENTIFIED\ BY\ ${keycloak.connectionsJpa.password};\n\ GRANT\ CONNECT,\ RESOURCE,\ DBA,\ GRANT\ ANY\ PRIVILEGE,\ UNLIMITED\ TABLESPACE\ TO\ ${keycloak.connectionsJpa.user};\n';\ do\ sleep\ 5;\ done diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java index 291769e06f..19b2c97c62 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java @@ -22,7 +22,7 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration { private int bindHttpPortOffset = 100; private int bindHttpPort = 8080; private int bindHttpsPortOffset = 0; - private int bindHttpsPort = Integer.valueOf(System.getProperty("auth.server.https.port", "8543")); + private int bindHttpsPort = Integer.getInteger("auth.server.https.port", 8543); private int debugPort = -1; private Path providersPath = Paths.get(System.getProperty("auth.server.home")); private int startupTimeoutInSeconds = 300; @@ -163,6 +163,4 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration { public void setImportFile(String importFile) { this.importFile = importFile; } - - } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java index 6a75210d66..382c055a40 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.commons.exec.StreamPumper; @@ -47,6 +48,7 @@ import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.descriptor.api.Descriptor; import org.keycloak.testsuite.arquillian.SuiteContext; +import org.keycloak.testsuite.model.StoreProvider; /** * @author mhajas @@ -54,7 +56,6 @@ import org.keycloak.testsuite.arquillian.SuiteContext; public class KeycloakQuarkusServerDeployableContainer implements DeployableContainer { private static final int DEFAULT_SHUTDOWN_TIMEOUT_SECONDS = 10; - private static final String AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE = "auth.server.quarkus.mapStorage.profile.config"; private static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class); @@ -182,9 +183,6 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta builder.environment().put("JAVA_OPTS", javaOpts); } - builder.environment().put("KEYCLOAK_ADMIN", "admin"); - builder.environment().put("KEYCLOAK_ADMIN_PASSWORD", "admin"); - if (restart.compareAndSet(false, true)) { deleteDirectory(configuration.getProvidersPath().resolve("data")); } @@ -216,15 +214,18 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta commands.add("-Djboss.node.name=" + configuration.getRoute()); } - String mapStorageProfile = System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE); - // only run build during restarts or when running cluster tests + final StoreProvider storeProvider = StoreProvider.getCurrentProvider(); - if (restart.get() || "ha".equals(System.getProperty("auth.server.quarkus.cluster.config"))) { + final Supplier shouldSetUpDb = () -> !restart.get() && !storeProvider.equals(StoreProvider.DEFAULT); + final Supplier getClusterConfig = () -> System.getProperty("auth.server.quarkus.cluster.config", "local"); + + // only run build during first execution of the server (if the DB is specified), restarts or when running cluster tests + if (restart.get() || shouldSetUpDb.get() || "ha".equals(getClusterConfig.get())) { commands.removeIf("--optimized"::equals); commands.add("--http-relative-path=/auth"); - if (mapStorageProfile == null) { - String cacheMode = System.getProperty("auth.server.quarkus.cluster.config", "local"); + if (!storeProvider.isMapStore()) { + String cacheMode = getClusterConfig.get(); if ("local".equals(cacheMode)) { commands.add("--cache=local"); @@ -234,7 +235,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta } } - addStorageOptions(commands); + addStorageOptions(storeProvider, commands); commands.addAll(getAdditionalBuildArgs()); @@ -243,34 +244,9 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta return commands.toArray(new String[0]); } - private void addStorageOptions(List commands) { - String mapStorageProfile = System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE); - - if (mapStorageProfile != null) { - // We need to drop optimized flag because --storage is build option therefore startup requires re-augmentation - commands.removeIf("--optimized"::equals); - - // As config is re-augmented on startup we need to also add --http-relative-path as ant build from - // integration-arquillian/servers/auth-server/quarkus/ant/configure.xml is replaced by build invoked on - // startup when we add new build option below - commands.add("--http-relative-path=/auth"); - - switch (mapStorageProfile) { - case "chm": - commands.add("--storage=" + mapStorageProfile); - break; - case "jpa": - commands.add("--storage=" + mapStorageProfile); - commands.add("--db-username=" + System.getProperty("keycloak.map.storage.connectionsJpa.url")); - commands.add("--db-password=" + System.getProperty("keycloak.map.storage.connectionsJpa.user")); - commands.add("--db-url=" + System.getProperty("keycloak.map.storage.connectionsJpa.password")); - break; - case "hotrod": - commands.add("--storage=" + mapStorageProfile); - // TODO: URL / username / password - break; - } - } + private void addStorageOptions(StoreProvider storeProvider, List commands) { + log.debugf("Store '%s' is used.", storeProvider.name()); + storeProvider.addStoreOptions(commands); } private void waitForReadiness() throws MalformedURLException, LifecycleException { diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/model/StoreProvider.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/model/StoreProvider.java new file mode 100644 index 0000000000..7742296cb2 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/model/StoreProvider.java @@ -0,0 +1,114 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.model; + +import org.keycloak.utils.StringUtil; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * @author Martin Bartos + */ +public enum StoreProvider { + CHM("chm") { + @Override + public void addStoreOptions(List commands) { + commands.add("--storage=" + getAlias()); + } + }, + JPA("jpa") { + @Override + public void addStoreOptions(List commands) { + commands.add("--storage=" + getAlias()); + getDbVendor().ifPresent(vendor -> commands.add("--db=" + vendor)); + commands.add("--db-url='" + System.getProperty("keycloak.map.storage.connectionsJpa.url") + "'"); + commands.add("--db-username=" + System.getProperty("keycloak.map.storage.connectionsJpa.user")); + commands.add("--db-password=" + System.getProperty("keycloak.map.storage.connectionsJpa.password")); + } + }, + HOTROD("hotrod") { + @Override + public void addStoreOptions(List commands) { + commands.add("--storage=" + getAlias()); + commands.add("--storage-hotrod-host='" + System.getProperty("keycloak.connectionsHotRod.host") + "'"); + commands.add("--storage-hotrod-username" + System.getProperty("keycloak.connectionsHotRod.username")); + commands.add("--storage-hotrod-password" + System.getProperty("keycloak.connectionsHotRod.password")); + } + }, + LEGACY("legacy") { + @Override + public void addStoreOptions(List commands) { + getDbVendor().ifPresent(vendor -> commands.add("--db=" + vendor)); + commands.add("--db-url='" + System.getProperty("keycloak.connectionsJpa.url") + "'"); + commands.add("--db-username=" + System.getProperty("keycloak.connectionsJpa.user")); + commands.add("--db-password=" + System.getProperty("keycloak.connectionsJpa.password")); + } + }, + DEFAULT("default") { + @Override + public void addStoreOptions(List commands) { + //nop + } + }; + + public static final String AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE = "auth.server.quarkus.mapStorage.profile.config"; + public static final String DB_VENDOR_PROPERTY = "keycloak.storage.connections.vendor"; + + private final String alias; + + public abstract void addStoreOptions(List commands); + + StoreProvider(String alias) { + this.alias = alias; + } + + public String getAlias() { + return alias; + } + + public boolean isLegacyStore() { + return this.equals(LEGACY); + } + + public boolean isMapStore() { + return !isLegacyStore() && !this.equals(DEFAULT); + } + + public static Optional getDbVendor() { + return Optional.ofNullable(System.getProperty(DB_VENDOR_PROPERTY)).filter(StringUtil::isNotBlank); + } + + public static StoreProvider getCurrentProvider() { + return getProviderByAlias(System.getProperty(AUTH_SERVER_QUARKUS_MAP_STORAGE_PROFILE, "")); + } + + /** + * Get Store Provider by alias + * + * @param alias alias + * @return store provider, LEGACY when vendor is specified, otherwise DEFAULT + */ + public static StoreProvider getProviderByAlias(String alias) { + return Arrays.stream(StoreProvider.values()) + .filter(f -> f.getAlias().equals(alias)) + .findFirst() + .orElseGet(() -> getDbVendor().isEmpty() ? DEFAULT : LEGACY); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index a450f7a670..0001dae64d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -656,9 +656,13 @@ ${auth.server.quarkus} - org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer + + org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer + ${auth.server.port.offset} - -Xms512m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true + -Xms512m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m + -Djava.net.preferIPv4Stack=true -Dauth.server.db.host=some + diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 2fb07cf45d..67de90301c 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -57,6 +57,7 @@ ${containers.home}/${auth.server.container} ${auth.server.home} + ${docker.container.testdb.ip} localhost ${auth.server.host} @@ -688,6 +689,7 @@ ${project.build.directory}/dependency/password-blacklists + ${keycloak.storage.connections.vendor} ${keycloak.connectionsJpa.driver} ${keycloak.connectionsJpa.url} ${keycloak.connectionsJpa.database}