[KEYCLOAK-19798] - Less verbose HTTP options and minor changes to property mappers
This commit is contained in:
parent
2f9a5aae0f
commit
37b36decbb
8 changed files with 68 additions and 16 deletions
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.quarkus.runtime.cli;
|
||||
|
||||
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
|
||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
|
||||
|
@ -509,6 +510,6 @@ public final class Picocli {
|
|||
}
|
||||
|
||||
public static String normalizeKey(String key) {
|
||||
return key.replace('-', '.');
|
||||
return replaceNonAlphanumericByUnderscores(key).replace('_', '.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ import picocli.CommandLine.Command;
|
|||
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --features=preview%n%n"
|
||||
+ " Enable metrics:%n%n"
|
||||
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --metrics-enabled=true%n%n"
|
||||
+ " Change the relative path:%n%n"
|
||||
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --http-relative-path=/auth%n%n"
|
||||
+ "You can also use the \"--auto-build\" option when starting the server to avoid running this command every time you change a configuration:%n%n"
|
||||
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} start --auto-build <OPTIONS>%n%n"
|
||||
+ "By doing that you have an additional overhead when the server is starting.",
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.jboss.logging.Logger;
|
|||
import io.smallrye.config.PropertiesConfigSource;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
|
||||
/**
|
||||
* <p>A configuration source for mapping configuration arguments to their corresponding properties so that they can be recognized
|
||||
|
@ -100,7 +102,17 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
|
|||
|
||||
log.tracef("Adding property [%s=%s] from command-line", key, value);
|
||||
properties.put(key, value);
|
||||
properties.put(getMappedPropertyName(key), value);
|
||||
|
||||
String mappedPropertyName = getMappedPropertyName(key);
|
||||
|
||||
properties.put(mappedPropertyName, value);
|
||||
|
||||
PropertyMapper mapper = PropertyMappers.getMapper(mappedPropertyName);
|
||||
|
||||
if (mapper != null) {
|
||||
properties.put(mapper.getFrom(), value);
|
||||
}
|
||||
|
||||
// to make lookup easier, we normalize the key
|
||||
properties.put(Picocli.normalizeKey(key), value);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
|
|||
public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) {
|
||||
ConfigValue value = PropertyMappers.getValue(context, name);
|
||||
|
||||
if (value == null) {
|
||||
if (value == null || value.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,13 @@ final class HttpPropertyMappers {
|
|||
.description("The used HTTP Host.")
|
||||
.paramLabel("host")
|
||||
.build(),
|
||||
builder().from("http.relative-path")
|
||||
.to("quarkus.http.root-path")
|
||||
.defaultValue("/")
|
||||
.description("Set the path relative to '/' for serving resources.")
|
||||
.paramLabel("path")
|
||||
.isBuildTimeProperty(true)
|
||||
.build(),
|
||||
builder().from("http.port")
|
||||
.to("quarkus.http.port")
|
||||
.defaultValue(String.valueOf(8080))
|
||||
|
@ -71,36 +78,37 @@ final class HttpPropertyMappers {
|
|||
.description("The file path to a private key in PEM format.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.certificate.key-store-file")
|
||||
builder().from("https.key-store.file")
|
||||
.to("quarkus.http.ssl.certificate.key-store-file")
|
||||
.defaultValue(getDefaultKeystorePathValue())
|
||||
.description("The key store which holds the certificate information instead of specifying separate files.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.certificate.key-store-password")
|
||||
builder().from("https.key-store.password")
|
||||
.to("quarkus.http.ssl.certificate.key-store-password")
|
||||
.description("The password of the key store file. If not given, the default (\"password\") is used.")
|
||||
.description("The password of the key store file.")
|
||||
.defaultValue("password")
|
||||
.paramLabel("password")
|
||||
.isMasked(true)
|
||||
.build(),
|
||||
builder().from("https.certificate.key-store-file-type")
|
||||
builder().from("https.key-store.type")
|
||||
.to("quarkus.http.ssl.certificate.key-store-file-type")
|
||||
.description("The type of the key store file. " +
|
||||
"If not given, the type is automatically detected based on the file name.")
|
||||
.paramLabel("type")
|
||||
.build(),
|
||||
builder().from("https.certificate.trust-store-file")
|
||||
builder().from("https.trust-store.file")
|
||||
.to("quarkus.http.ssl.certificate.trust-store-file")
|
||||
.description("The trust store which holds the certificate information of the certificates to trust.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.certificate.trust-store-password")
|
||||
builder().from("https.trust-store.password")
|
||||
.to("quarkus.http.ssl.certificate.trust-store-password")
|
||||
.description("The password of the trust store file.")
|
||||
.paramLabel("password")
|
||||
.isMasked(true)
|
||||
.build(),
|
||||
builder().from("https.certificate.trust-store-file-type")
|
||||
builder().from("https.trust-store.type")
|
||||
.to("quarkus.http.ssl.certificate.trust-store-file-type")
|
||||
.defaultValue(getDefaultKeystorePathValue())
|
||||
.description("The type of the trust store file. " +
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.quarkus.runtime.configuration.mappers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
|
@ -48,7 +49,7 @@ public class PropertyMapper {
|
|||
PropertyMapper(String from, String to, String defaultValue, BiFunction<String, ConfigSourceInterceptorContext, String> mapper,
|
||||
String mapFrom, boolean buildTime, String description, String paramLabel, boolean mask, Iterable<String> expectedValues, ConfigCategory category) {
|
||||
this.from = MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + from;
|
||||
this.to = to;
|
||||
this.to = to == null ? this.from : to;
|
||||
this.defaultValue = defaultValue;
|
||||
this.mapper = mapper == null ? PropertyMapper::defaultTransformer : mapper;
|
||||
this.mapFrom = mapFrom;
|
||||
|
@ -105,6 +106,10 @@ public class PropertyMapper {
|
|||
// if not defined, return the current value from the property as a default if the property is not explicitly set
|
||||
if (defaultValue == null
|
||||
|| (current != null && !current.getConfigSourceName().equalsIgnoreCase("default values"))) {
|
||||
if (defaultValue == null && mapper != null) {
|
||||
String value = current == null ? null : current.getValue();
|
||||
return ConfigValue.builder().withName(to).withValue(mapper.apply(value, context)).build();
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
@ -245,6 +250,11 @@ public class PropertyMapper {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder expectedValues(String... expectedValues) {
|
||||
this.expectedValues = Arrays.asList(expectedValues);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder isBuildTimeProperty(boolean isBuildTime) {
|
||||
this.isBuildTimeProperty = isBuildTime;
|
||||
return this;
|
||||
|
@ -260,6 +270,13 @@ public class PropertyMapper {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder type(Class<Boolean> type) {
|
||||
if (Boolean.class.equals(type)) {
|
||||
expectedValues(Boolean.TRUE.toString(), Boolean.FALSE.toString());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyMapper build() {
|
||||
return new PropertyMapper(from, to, defaultValue, mapper, mapFrom, isBuildTimeProperty, description, paramLabel, isMasked, expectedValues, category);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,13 @@ public final class PropertyMappers {
|
|||
}
|
||||
|
||||
boolean isBuildTimeProperty = MAPPERS.entrySet().stream()
|
||||
.anyMatch(entry -> entry.getValue().getFrom().equals(name) && entry.getValue().isBuildTime());
|
||||
.anyMatch(new Predicate<Map.Entry<String, PropertyMapper>>() {
|
||||
@Override
|
||||
public boolean test(Map.Entry<String, PropertyMapper> entry) {
|
||||
PropertyMapper mapper = entry.getValue();
|
||||
return (mapper.getFrom().equals(name) || mapper.getTo().equals(name)) && mapper.isBuildTime();
|
||||
}
|
||||
});
|
||||
|
||||
if (!isBuildTimeProperty) {
|
||||
Optional<String> prefixedMapper = PropertyMappers.getPrefixedMapper(name);
|
||||
|
@ -126,6 +132,12 @@ public final class PropertyMappers {
|
|||
}
|
||||
|
||||
public static PropertyMapper getMapper(String property) {
|
||||
PropertyMapper mapper = MAPPERS.get(property);
|
||||
|
||||
if (mapper != null) {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
return MAPPERS.values().stream().filter(new Predicate<PropertyMapper>() {
|
||||
@Override
|
||||
public boolean test(PropertyMapper propertyMapper) {
|
||||
|
|
|
@ -7,10 +7,10 @@ db.password = keycloak
|
|||
http.enabled=true
|
||||
|
||||
# SSL
|
||||
https.certificate.key-store-file=${kc.home.dir}/conf/keycloak.jks
|
||||
https.certificate.key-store-password=secret
|
||||
https.certificate.trust-store-file=${kc.home.dir}/conf/keycloak.truststore
|
||||
https.certificate.trust-store-password=secret
|
||||
https.key-store.file=${kc.home.dir}/conf/keycloak.jks
|
||||
https.key-store.password=secret
|
||||
https.trust-store.file=${kc.home.dir}/conf/keycloak.truststore
|
||||
https.trust-store.password=secret
|
||||
https.client-auth=REQUEST
|
||||
|
||||
# Proxy
|
||||
|
|
Loading…
Reference in a new issue