8000 Persisted config source not loading properties at runtime by pedroigor · Pull Request #12157 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ jobs:

- name: Run Quarkus Storage Tests
run: |
./mvnw clean install -nsu -B -f quarkus/tests/pom.xml -Ptest-database -Dtest=PostgreSQLStartDatabaseTest | misc/log/trimmer.sh
./mvnw clean install -nsu -B -f quarkus/tests/pom.xml -Ptest-database -Dtest=PostgreSQLDistTest | misc/log/trimmer.sh
TEST_RESULT=${PIPESTATUS[0]}
find . -path '*/target/surefire-reports/*.xml' | zip -q reports-quarkus-tests.zip -@
exit $TEST_RESULT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import io.quarkus.bootstrap.runner.RunnerClassLoader;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ProfileManager;
import org.apache.commons.lang3.SystemUtils;
Expand All @@ -49,11 +48,11 @@ public final class Environment {
private Environment() {}

public static Boolean isRebuild() {
return !isRuntimeMode();
return Boolean.getBoolean("quarkus.launch.rebuild");
}

public static Boolean isRuntimeMode() {
return Thread.currentThread().getContextClassLoader() instanceof RunnerClassLoader;
return !isRebuild();
}

public static String getHomeDir() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public String getValue(String propertyName) {
}

private static Map<String, String> readProperties() {
if (!Environment.isRebuild()) {
if (Environment.isRuntimeMode()) {
InputStream fileStream = loadPersistedConfig();

if (fileStream == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ metrics-enabled=false
%import_export.http-enabled=true
%import_export.hostname-strict=false
%import_export.hostname-strict-https=false
%import_export.cluster=local

#logging defaults
log-console-output=default
Expand Down
8 changes: 8 additions & 0 deletions quarkus/tests/integration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@
<artifactId>approvaltests</artifactId>
<version>${approvaltests.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mariadb</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class CLITestExtension extends QuarkusMainTestExtension {
private static final String KEY_VALUE_SEPARATOR = "[= ]";
private KeycloakDistribution dist;
private final Set<String> testSysProps = new HashSet<>();
private DatabaseContainer databaseContainer;

@Override
public void beforeEach(ExtensionContext context) throws Exception {
Expand Down Expand Up @@ -81,6 +82,8 @@ public void beforeEach(ExtensionContext context) throws Exception {
}
}

configureDatabase(context);

if (distConfig != null) {
onKeepServerAlive(context.getRequiredTestMethod().getAnnotation(KeepServerAlive.class));

Expand All @@ -96,7 +99,6 @@ public void beforeEach(ExtensionContext context) throws Exception {
}
} else {
configureProfile(context);
configureDatabase(context);
super.beforeEach(context);
}
}
Expand Down Expand Up @@ -148,6 +150,10 @@ private void reset() {
for (String property : testSysProps) {
System.getProperties().remove(property);
}
if (databaseContainer != null && databaseContainer.isRunning()) {
databaseContainer.stop();
databaseContainer = null;
}
}

@Override
Expand Down Expand Up @@ -237,10 +243,22 @@ private void configureDatabase(ExtensionContext context) {
WithDatabase database = context.getTestClass().orElse(Object.class).getDeclaredAnnotation(WithDatabase.class);

if (database != null) {
configureDevServices();
setProperty("kc.db", database.alias());
// databases like mssql are very strict about password policy
setProperty("kc.db-password", "Password1!");
if (dist == null) {
configureDevServices();
setProperty("kc.db", database.alias());
setProperty("kc.db-password", DatabaseContainer.DEFAULT_PASSWORD);
} else {
databaseContainer = new DatabaseContainer(database.alias());

databaseContainer.start();

dist.setProperty("db", database.alias());
dist.setProperty("db-username", databaseContainer.getUsername());
dist.setProperty("db-password", databaseContainer.getPassword());
dist.setProperty("db-url", databaseContainer.getJdbcUrl());

dist.start(List.of("build"));
}
} else {
// This is for re-creating the H2 database instead of using the default in home
setProperty("kc.db-url-path", new QuarkusPlatform().getTmpDirectory().getAbsolutePath());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2021 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.it.junit5.extension;

import java.time.Duration;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.containers.PostgreSQLContainer;

public class DatabaseContainer {

static final String DEFAULT_PASSWORD = "Password1!";

private final String alias;
private JdbcDatabaseContainer container;

DatabaseContainer(String alias) {
this.alias = alias;
}

void start() {
container = createContainer()
.withDatabaseName("keycloak")
.withUsername(getUsername())
.withPassword(getPassword());

container.withStartupTimeout(Duration.ofMinutes(5)).start();
}

boolean isRunning() {
return container.isRunning();
}

String getJdbcUrl() {
return container.getJdbcUrl();
}

String getUsername() {
return "keycloak";
Comment thread
pedroigor marked this conversation as resolved.
Resolved
}

String getPassword() {
return DEFAULT_PASSWORD;
}

void stop() {
container.stop();
container = null;
}

private JdbcDatabaseContainer createContainer() {
switch (alias) {
case "postgres":
return new PostgreSQLContainer("postgres:alpine");
case "mariadb":
return new MariaDBContainer("mariadb:10.5.9");
default:
throw new RuntimeException("Unsupported database: " + alias);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@ enum ReInstall {
}

ReInstall reInstall() default ReInstall.BEFORE_ALL;

/**
* If any build option must be unset after the running the build command.
*/
boolean removeBuildOptionsAfterBuild() default false;
}

Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ private static KeycloakDistribution createRawDistribution(DistributionTest confi
return new RawKeycloakDistribution(
config.debug(),
config.keepAlive(),
!DistributionTest.ReInstall.NEVER.equals(config.reInstall()));
!DistributionTest.ReInstall.NEVER.equals(config.reInstall()),
config.removeBuildOptionsAfterBuild());
}

private final Function<DistributionTest, KeycloakDistribution> factory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@

/**
* The database name as per database aliases.
*
* @return the database alias
*/
String alias();
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ default void deleteQuarkusProperties() {
default void copyOrReplaceFileFromClasspath(String file, Path distDir) {
throw new RuntimeException("Not implemented");
}

default void removeProperty(String db) {
throw new RuntimeException("Not implemented");
}
}
10BC8
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.List;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.net.ssl.HostnameVerifier;
Expand All @@ -54,6 +55,9 @@

import org.keycloak.common.Version;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.command.Build;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;

import static org.keycloak.quarkus.runtime.Environment.LAUNCH_MODE;

Expand All @@ -69,13 +73,15 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
private int httpPort;
private boolean debug;
private boolean reCreate;
private boolean removeBuildOptionsAfterBuild;
private ExecutorService outputExecutor;
private boolean inited = false;

public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate) {
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate, boolean removeBuildOptionsAfterBuild) {
this.debug = debug;
this.manualStop = manualStop;
this.reCreate = reCreate;
this.removeBuildOptionsAfterBuild = removeBuildOptionsAfterBuild;
this.distPath = prepareDistribution();
}

Expand All @@ -98,6 +104,11 @@ public void start(List<String> arguments) {
stop();
throw new RuntimeException("Failed to start the server", cause);
} finally {
if (arguments.contains(Build.NAME) && removeBuildOptionsAfterBuild) {
for (PropertyMapper mapper : PropertyMappers.getBuildTimeMappers()) {
removeProperty(mapper.getFrom().substring(3));
}
}
if (!manualStop) {
stop();
}
Expand All @@ -108,7 +119,6 @@ public void start(List<String> arguments) {
public void stop() {
if (isRunning()) {
try {

if (Environment.isWindows()) {
// On Windows, we're executing kc.bat in a runtime as "keycloak",
// so tha java process is an actual child process
Expand Down Expand Up @@ -409,12 +419,27 @@ public void setManualStop(boolean manualStop) {

@Override
public void setProperty(String key, String value) {
setProperty(key, value, distPath.resolve("conf").resolve("keycloak.conf").toFile());
updateProperties(properties -> properties.put(key, value), distPath.resolve("conf").resolve("keycloak.conf").toFile());
}

@Override
public void removeProperty(String key) {
updateProperties(new Consumer<Properties>() {
@Override
public void accept(Properties properties) {
properties.remove(key);
}
}, distPath.resolve("conf").resolve("keycloak.conf").toFile());
}

@Override
public void setQuarkusProperty(String key, String value) {
setProperty(key, value, getQuarkusPropertiesFile());
updateProperties(new Consumer<Properties>() {
@Override
public void accept(Properties properties) {
properties.put(key, value);
}
}, getQuarkusPropertiesFile());
}

@Override
Expand All @@ -439,27 +464,27 @@ public void copyOrReplaceFileFromClasspath(String file, Path targetFile) {
}
}

private void setProperty(String key, String value, File confFile) {
private void updateProperties(Consumer<Properties> propertiesConsumer, File propertiesFile) {
Properties properties = new Properties();

if (confFile.exists()) {
if (propertiesFile.exists()) {
try (
FileInputStream in = new FileInputStream(confFile);
FileInputStream in = new FileInputStream(propertiesFile);
) {

properties.load(in);
} catch (Exception e) {
throw new RuntimeException("Failed to update " + confFile, e);
throw new RuntimeException("Failed to update " + propertiesFile, e);
}
}

try (
FileOutputStream out = new FileOutputStream(confFile)
FileOutputStream out = new FileOutputStream(propertiesFile)
) {
properties.put(key, value);
propertiesConsumer.accept(properties);
properties.store(out, "");
} catch (Exception e) {
throw new RuntimeException("Failed to update " + confFile, e);
throw new RuntimeException("Failed to update " + propertiesFile, e);
}
}

Expand Down
Loading
0