diff --git a/distribution/server-x/src/main/content/bin/kc.sh b/distribution/server-x/src/main/content/bin/kc.sh index bf1aa15da7..696ad7222d 100644 --- a/distribution/server-x/src/main/content/bin/kc.sh +++ b/distribution/server-x/src/main/content/bin/kc.sh @@ -38,6 +38,10 @@ do shift fi ;; + --config) + SERVER_OPTS="$SERVER_OPTS -Dkeycloak.config.file=$2" + shift + ;; --) shift break;; diff --git a/distribution/server-x/src/main/content/conf/keycloak.properties b/distribution/server-x/src/main/content/conf/keycloak.properties new file mode 100644 index 0000000000..25b2649fed --- /dev/null +++ b/distribution/server-x/src/main/content/conf/keycloak.properties @@ -0,0 +1,7 @@ +# Datasource +datasource.dialect=org.hibernate.dialect.H2Dialect +datasource.driver=org.h2.jdbcx.JdbcDataSource +datasource.url = jdbc:h2:file:${keycloak.home.dir}/data/keycloakdb;;AUTO_SERVER=TRUE +datasource.username = sa +datasource.password = keycloak +datasource.jdbc.transactions=xa \ No newline at end of file diff --git a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakConfigSourceProvider.java b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakConfigSourceProvider.java index b0dfbc539c..eed436c6ba 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakConfigSourceProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakConfigSourceProvider.java @@ -17,33 +17,55 @@ package org.keycloak.provider.quarkus; +import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.List; import io.quarkus.runtime.configuration.DeploymentProfileConfigSource; import io.quarkus.runtime.configuration.ExpandingConfigSource; import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.config.spi.ConfigSourceProvider; +import org.jboss.logging.Logger; public class KeycloakConfigSourceProvider implements ConfigSourceProvider { + private static final Logger log = Logger.getLogger(KeycloakConfigSourceProvider.class); private static final String KEYCLOAK_CONFIG_FILE_PROP = "keycloak.config.file"; private static final String KEYCLOAK_CONFIG_FILE_ENV = "KEYCLOAK_CONFIG_FILE"; @Override public Iterable getConfigSources(ClassLoader forClassLoader) { - ArrayList sources = new ArrayList<>(); + List sources = new ArrayList<>(); - sources.add(wrap(new KeycloakPropertiesConfigSource.InJar())); + String filePath = System.getProperty(KEYCLOAK_CONFIG_FILE_PROP); - String fileName = System.getProperty(KEYCLOAK_CONFIG_FILE_PROP); + if (filePath == null) + filePath = System.getenv(KEYCLOAK_CONFIG_FILE_ENV); - if (fileName == null) - fileName = System.getenv(KEYCLOAK_CONFIG_FILE_ENV); + if (filePath == null) { + String homeDir = System.getProperty("keycloak.home.dir"); - if (fileName != null) - sources.add(wrap(new KeycloakPropertiesConfigSource.InFileSystem(fileName))); + if (homeDir != null) { + File file = Paths.get(homeDir, "conf", KeycloakPropertiesConfigSource.KEYCLOAK_PROPERTIES).toFile(); + + if (file.exists()) { + filePath = file.getAbsolutePath(); + } + } + } + + if (filePath != null) { + sources.add(wrap(new KeycloakPropertiesConfigSource.InFileSystem(filePath))); + } + + // fall back to the default configuration within the server classpath + if (sources.isEmpty()) { + log.debug("Loading the default server configuration"); + sources.add(wrap(new KeycloakPropertiesConfigSource.InJar())); + } return sources; diff --git a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakPropertiesConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakPropertiesConfigSource.java index 4b08a10e70..ce2cf01978 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakPropertiesConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/KeycloakPropertiesConfigSource.java @@ -35,8 +35,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; +import org.jboss.logging.Logger; + import io.smallrye.config.PropertiesConfigSource; +import static org.keycloak.common.util.StringPropertyReplacer.replaceProperties; import static org.keycloak.provider.quarkus.MicroProfileConfigProvider.NS_KEYCLOAK; import static org.keycloak.provider.quarkus.MicroProfileConfigProvider.NS_QUARKUS; @@ -45,6 +48,7 @@ import static org.keycloak.provider.quarkus.MicroProfileConfigProvider.NS_QUARKU */ public abstract class KeycloakPropertiesConfigSource extends PropertiesConfigSource { + private static final Logger log = Logger.getLogger(KeycloakPropertiesConfigSource.class); static final String KEYCLOAK_PROPERTIES = "keycloak.properties"; KeycloakPropertiesConfigSource(InputStream is, int ordinal) { @@ -85,6 +89,9 @@ public abstract class KeycloakPropertiesConfigSource extends PropertiesConfigSou } else { is = cl.getResourceAsStream(fileName); } + if (is != null) { + log.debug("Loading the server configuration from the classpath"); + } return is; } } @@ -99,6 +106,7 @@ public abstract class KeycloakPropertiesConfigSource extends PropertiesConfigSou final Path path = Paths.get(fileName); if (Files.exists(path)) { try { + log.debugf("Loading the server configuration from %s", fileName); return Files.newInputStream(path); } catch (NoSuchFileException | FileNotFoundException e) { return null; @@ -113,15 +121,23 @@ public abstract class KeycloakPropertiesConfigSource extends PropertiesConfigSou private static Map transform(Map properties) { Map result = new HashMap<>(properties.size()); - properties.keySet().forEach(k -> result.put(transformKey(k), properties.get(k))); + properties.keySet().forEach(k -> result.put(transformKey(k), replaceProperties(properties.get(k)))); return result; } private static String transformKey(String key) { + String namespace; + String[] keyParts = key.split("\\."); + String extension = keyParts[0]; + String profile = ""; - String namespace, prefix = (key.split("\\."))[0]; + if (extension.startsWith("%")) { + profile = String.format("%s.", keyParts[0]); + extension = keyParts[1]; + key = key.substring(key.indexOf('.') + 1); + } - switch (prefix) { + switch (extension) { case "datasource": case "http": case "log": @@ -131,8 +147,7 @@ public abstract class KeycloakPropertiesConfigSource extends PropertiesConfigSou namespace = NS_KEYCLOAK; } - return namespace + "." + key; + return profile + namespace + "." + key; } - }