Merge pull request #40225 from radcortez/sr-config-3.8.0
Update SmallRye Config to 3.8.1
This commit is contained in:
commit
9a768bbec0
|
@ -51,7 +51,7 @@
|
|||
<microprofile-lra.version>2.0</microprofile-lra.version>
|
||||
<microprofile-openapi.version>3.1.1</microprofile-openapi.version>
|
||||
<smallrye-common.version>2.3.0</smallrye-common.version>
|
||||
<smallrye-config.version>3.7.1</smallrye-config.version>
|
||||
<smallrye-config.version>3.8.1</smallrye-config.version>
|
||||
<smallrye-health.version>4.1.0</smallrye-health.version>
|
||||
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
|
||||
<smallrye-open-api.version>3.10.0</smallrye-open-api.version>
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-development-mode-spi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-hibernate-validator-spi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-class-change-agent</artifactId>
|
||||
|
|
|
@ -10,6 +10,10 @@ import io.quarkus.builder.item.MultiBuildItem;
|
|||
|
||||
public final class ConfigClassBuildItem extends MultiBuildItem {
|
||||
private final Class<?> configClass;
|
||||
/**
|
||||
* All the config interfaces registered for this config mapping (including the nested ones)
|
||||
*/
|
||||
private final Set<Class<?>> configComponentInterfaces;
|
||||
private final Set<Type> types;
|
||||
private final Set<String> generatedClasses;
|
||||
private final String prefix;
|
||||
|
@ -19,12 +23,14 @@ public final class ConfigClassBuildItem extends MultiBuildItem {
|
|||
|
||||
public ConfigClassBuildItem(
|
||||
final Class<?> configClass,
|
||||
final Set<Class<?>> configComponentInterfaces,
|
||||
final Set<Type> types,
|
||||
final Set<String> generatedClasses,
|
||||
final String prefix,
|
||||
final Kind kind) {
|
||||
|
||||
this.configClass = configClass;
|
||||
this.configComponentInterfaces = configComponentInterfaces;
|
||||
this.types = types;
|
||||
this.generatedClasses = generatedClasses;
|
||||
this.prefix = prefix;
|
||||
|
@ -36,6 +42,10 @@ public final class ConfigClassBuildItem extends MultiBuildItem {
|
|||
return configClass;
|
||||
}
|
||||
|
||||
public Set<Class<?>> getConfigComponentInterfaces() {
|
||||
return configComponentInterfaces;
|
||||
}
|
||||
|
||||
public Set<Type> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
|
|
@ -524,12 +524,6 @@ public final class BuildTimeConfigurationReader {
|
|||
buildTimeRunTimeValues.putAll(getDefaults(config, buildTimeRunTimePatternMap));
|
||||
runTimeDefaultValues.putAll(getDefaults(runtimeConfig, runTimePatternMap));
|
||||
|
||||
// Register defaults for Mappings
|
||||
// Runtime defaults are added in ConfigGenerationBuildStep.generateBuilders to include user mappings
|
||||
for (ConfigClassWithPrefix buildTimeRunTimeMapping : buildTimeRunTimeMappings) {
|
||||
buildTimeRunTimeValues.putAll(ConfigMappings.getDefaults(buildTimeRunTimeMapping));
|
||||
}
|
||||
|
||||
Set<String> registeredRoots = allRoots.stream().map(RootDefinition::getName).collect(toSet());
|
||||
registeredRoots.add("quarkus");
|
||||
Set<String> allProperties = getAllProperties(registeredRoots);
|
||||
|
@ -1118,7 +1112,7 @@ public final class BuildTimeConfigurationReader {
|
|||
}
|
||||
});
|
||||
|
||||
String[] profiles = config.getProfiles().toArray(String[]::new);
|
||||
List<String> profiles = config.getProfiles();
|
||||
for (String property : builder.build().getPropertyNames()) {
|
||||
properties.add(ProfileConfigSourceInterceptor.activeName(property, profiles));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ import io.quarkus.deployment.builditem.ConfigClassBuildItem;
|
|||
import io.quarkus.deployment.builditem.ConfigClassBuildItem.Kind;
|
||||
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
|
||||
import io.quarkus.deployment.util.ReflectUtil;
|
||||
import io.quarkus.hibernate.validator.spi.AdditionalConstrainedClassBuildItem;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
import io.smallrye.config.ConfigMappingInterface;
|
||||
import io.smallrye.config.ConfigMappingInterface.LeafProperty;
|
||||
|
@ -46,7 +48,9 @@ public class ConfigMappingUtils {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses,
|
||||
DotName configAnnotation) {
|
||||
|
||||
for (AnnotationInstance instance : combinedIndex.getIndex().getAnnotations(configAnnotation)) {
|
||||
|
@ -61,7 +65,7 @@ public class ConfigMappingUtils {
|
|||
String prefix = Optional.ofNullable(annotationPrefix).map(AnnotationValue::asString).orElse("");
|
||||
Kind configClassKind = getConfigClassType(instance);
|
||||
processConfigClass(configClassWithPrefix(configClass, prefix), configClassKind, true, combinedIndex,
|
||||
generatedClasses, reflectiveClasses, configClasses);
|
||||
generatedClasses, reflectiveClasses, reflectiveMethods, configClasses, additionalConstrainedClasses);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,8 +73,11 @@ public class ConfigMappingUtils {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses) {
|
||||
processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, configClasses, CONFIG_MAPPING_NAME);
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses) {
|
||||
processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, reflectiveMethods, configClasses,
|
||||
additionalConstrainedClasses, CONFIG_MAPPING_NAME);
|
||||
}
|
||||
|
||||
public static void processExtensionConfigMapping(
|
||||
|
@ -78,10 +85,12 @@ public class ConfigMappingUtils {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses) {
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses) {
|
||||
|
||||
processConfigClass(configClass, Kind.MAPPING, false, combinedIndex, generatedClasses, reflectiveClasses,
|
||||
configClasses);
|
||||
reflectiveMethods, configClasses, additionalConstrainedClasses);
|
||||
}
|
||||
|
||||
private static void processConfigClass(
|
||||
|
@ -91,30 +100,37 @@ public class ConfigMappingUtils {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses) {
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses) {
|
||||
|
||||
Class<?> configClass = configClassWithPrefix.getKlass();
|
||||
String prefix = configClassWithPrefix.getPrefix();
|
||||
|
||||
List<ConfigMappingMetadata> configMappingsMetadata = ConfigMappingLoader.getConfigMappingsMetadata(configClass);
|
||||
Set<String> generatedClassesNames = new HashSet<>();
|
||||
// all the config interfaces including nested ones
|
||||
Set<Class<?>> configComponentInterfaces = new HashSet<>();
|
||||
configMappingsMetadata.forEach(mappingMetadata -> {
|
||||
generatedClassesNames.add(mappingMetadata.getClassName());
|
||||
// This is the generated implementation of the mapping by SmallRye Config.
|
||||
byte[] classBytes = mappingMetadata.getClassBytes();
|
||||
generatedClasses.produce(new GeneratedClassBuildItem(isApplicationClass, mappingMetadata.getClassName(),
|
||||
mappingMetadata.getClassBytes()));
|
||||
// Register the interface and implementation methods for reflection. This is required for Bean Validation.
|
||||
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getInterfaceType()).methods().build());
|
||||
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()).methods().build());
|
||||
// Register also the interface hierarchy
|
||||
for (Class<?> parent : getHierarchy(mappingMetadata.getInterfaceType())) {
|
||||
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(parent).methods().build());
|
||||
}
|
||||
classBytes));
|
||||
additionalConstrainedClasses.produce(AdditionalConstrainedClassBuildItem.of(mappingMetadata.getClassName(),
|
||||
classBytes));
|
||||
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()).constructors().build());
|
||||
reflectiveMethods
|
||||
.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getDefaults", new String[0]));
|
||||
reflectiveMethods.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getNames", new String[0]));
|
||||
|
||||
configComponentInterfaces.add(mappingMetadata.getInterfaceType());
|
||||
|
||||
processProperties(mappingMetadata.getInterfaceType(), reflectiveClasses);
|
||||
});
|
||||
|
||||
configClasses.produce(new ConfigClassBuildItem(configClass, collectTypes(combinedIndex, configClass),
|
||||
configClasses.produce(new ConfigClassBuildItem(configClass, configComponentInterfaces,
|
||||
collectTypes(combinedIndex, configClass),
|
||||
generatedClassesNames, prefix, configClassKind));
|
||||
}
|
||||
|
||||
|
@ -125,7 +141,6 @@ public class ConfigMappingUtils {
|
|||
ConfigMappingInterface mapping = ConfigMappingLoader.getConfigMapping(configClass);
|
||||
for (Property property : mapping.getProperties()) {
|
||||
Class<?> returnType = property.getMethod().getReturnType();
|
||||
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(returnType).methods().build());
|
||||
|
||||
if (property.hasConvertWith()) {
|
||||
Class<? extends Converter<?>> convertWith;
|
||||
|
|
|
@ -1197,24 +1197,24 @@ public final class RunTimeConfigurationGenerator {
|
|||
Object.class);
|
||||
|
||||
private void generateUnknownFilter() {
|
||||
Set<String> mappedProperties = new HashSet<>();
|
||||
Set<String> names = new HashSet<>();
|
||||
for (ConfigClassWithPrefix buildTimeMapping : buildTimeConfigResult.getBuildTimeMappings()) {
|
||||
mappedProperties.addAll(ConfigMappings.getKeys(buildTimeMapping));
|
||||
names.addAll(ConfigMappings.getProperties(buildTimeMapping).keySet());
|
||||
}
|
||||
for (ConfigClassWithPrefix staticConfigMapping : buildTimeConfigResult.getBuildTimeRunTimeMappings()) {
|
||||
mappedProperties.addAll(ConfigMappings.getKeys(staticConfigMapping));
|
||||
names.addAll(ConfigMappings.getProperties(staticConfigMapping).keySet());
|
||||
}
|
||||
for (ConfigClassWithPrefix runtimeConfigMapping : buildTimeConfigResult.getRunTimeMappings()) {
|
||||
mappedProperties.addAll(ConfigMappings.getKeys(runtimeConfigMapping));
|
||||
names.addAll(ConfigMappings.getProperties(runtimeConfigMapping).keySet());
|
||||
}
|
||||
|
||||
// Add a method that generates a KeyMap that can check if a property is mapped by a @ConfigMapping
|
||||
MethodCreator mc = cc.getMethodCreator(C_MAPPED_PROPERTIES);
|
||||
mc.setModifiers(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC);
|
||||
ResultHandle keyMap = mc.newInstance(KM_NEW);
|
||||
for (String mappedProperty : mappedProperties) {
|
||||
ResultHandle mappedPropertyKeyMap = mc.invokeVirtualMethod(KM_FIND_OR_ADD, keyMap, mc.load(mappedProperty));
|
||||
mc.invokeVirtualMethod(KM_PUT_ROOT_VALUE, mappedPropertyKeyMap, mc.load(true));
|
||||
for (String name : names) {
|
||||
mc.invokeVirtualMethod(KM_PUT_ROOT_VALUE, mc.invokeVirtualMethod(KM_FIND_OR_ADD, keyMap, mc.load(name)),
|
||||
mc.load(true));
|
||||
}
|
||||
|
||||
mc.returnValue(keyMap);
|
||||
|
|
|
@ -123,8 +123,7 @@ public class ConfigDescriptionBuildStep {
|
|||
private void processMappings(List<ConfigClassWithPrefix> mappings, List<ConfigDescriptionBuildItem> descriptionBuildItems,
|
||||
Properties javaDocProperties, ConfigPhase configPhase) {
|
||||
for (ConfigClassWithPrefix mapping : mappings) {
|
||||
Map<String, Property> properties = ConfigMappings.getProperties(mapping).get(mapping.getKlass())
|
||||
.get(mapping.getPrefix());
|
||||
Map<String, Property> properties = ConfigMappings.getProperties(mapping);
|
||||
for (Map.Entry<String, Property> entry : properties.entrySet()) {
|
||||
String propertyName = entry.getKey();
|
||||
Property property = entry.getValue();
|
||||
|
|
|
@ -59,6 +59,7 @@ import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
|
|||
import io.quarkus.deployment.builditem.StaticInitConfigBuilderBuildItem;
|
||||
import io.quarkus.deployment.builditem.SuppressNonRuntimeConfigChangedWarningBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
|
||||
import io.quarkus.deployment.configuration.BuildTimeConfigurationReader;
|
||||
import io.quarkus.deployment.configuration.RunTimeConfigurationGenerator;
|
||||
import io.quarkus.deployment.configuration.tracker.ConfigTrackingConfig;
|
||||
|
@ -73,6 +74,7 @@ import io.quarkus.gizmo.FieldDescriptor;
|
|||
import io.quarkus.gizmo.MethodCreator;
|
||||
import io.quarkus.gizmo.MethodDescriptor;
|
||||
import io.quarkus.gizmo.ResultHandle;
|
||||
import io.quarkus.hibernate.validator.spi.AdditionalConstrainedClassBuildItem;
|
||||
import io.quarkus.paths.PathCollection;
|
||||
import io.quarkus.runtime.LaunchMode;
|
||||
import io.quarkus.runtime.annotations.StaticInitSafe;
|
||||
|
@ -86,7 +88,6 @@ import io.quarkus.runtime.configuration.RuntimeConfigBuilder;
|
|||
import io.quarkus.runtime.configuration.RuntimeOverrideConfigSource;
|
||||
import io.quarkus.runtime.configuration.RuntimeOverrideConfigSourceBuilder;
|
||||
import io.quarkus.runtime.configuration.StaticInitConfigBuilder;
|
||||
import io.smallrye.config.ConfigMappings;
|
||||
import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix;
|
||||
import io.smallrye.config.ConfigSourceFactory;
|
||||
import io.smallrye.config.ConfigSourceInterceptor;
|
||||
|
@ -176,19 +177,23 @@ public class ConfigGenerationBuildStep {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses) {
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses) {
|
||||
|
||||
processConfigMapping(combinedIndex, generatedClasses, reflectiveClasses, configClasses);
|
||||
processConfigMapping(combinedIndex, generatedClasses, reflectiveClasses, reflectiveMethods, configClasses,
|
||||
additionalConstrainedClasses);
|
||||
|
||||
List<ConfigClassWithPrefix> buildTimeRunTimeMappings = configItem.getReadResult().getBuildTimeRunTimeMappings();
|
||||
for (ConfigClassWithPrefix buildTimeRunTimeMapping : buildTimeRunTimeMappings) {
|
||||
processExtensionConfigMapping(buildTimeRunTimeMapping, combinedIndex, generatedClasses, reflectiveClasses,
|
||||
configClasses);
|
||||
reflectiveMethods, configClasses, additionalConstrainedClasses);
|
||||
}
|
||||
|
||||
List<ConfigClassWithPrefix> runTimeMappings = configItem.getReadResult().getRunTimeMappings();
|
||||
for (ConfigClassWithPrefix runTimeMapping : runTimeMappings) {
|
||||
processExtensionConfigMapping(runTimeMapping, combinedIndex, generatedClasses, reflectiveClasses, configClasses);
|
||||
processExtensionConfigMapping(runTimeMapping, combinedIndex, generatedClasses, reflectiveClasses, reflectiveMethods,
|
||||
configClasses, additionalConstrainedClasses);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,14 +208,6 @@ public class ConfigGenerationBuildStep {
|
|||
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) throws Exception {
|
||||
|
||||
Map<String, String> defaultValues = new HashMap<>();
|
||||
// Default values from extensions @ConfigMapping
|
||||
for (ConfigClassWithPrefix runTimeMapping : configItem.getReadResult().getRunTimeMappings()) {
|
||||
defaultValues.putAll(ConfigMappings.getDefaults(runTimeMapping));
|
||||
}
|
||||
// Default values from user @ConfigMapping
|
||||
for (ConfigMappingBuildItem configMapping : configMappings) {
|
||||
defaultValues.putAll(ConfigMappings.getDefaults(configMapping.toConfigClassWithPrefix()));
|
||||
}
|
||||
// Default values from @ConfigRoot
|
||||
defaultValues.putAll(configItem.getReadResult().getRunTimeDefaultValues());
|
||||
// Default values from build item RunTimeConfigurationDefaultBuildItem override
|
||||
|
@ -218,7 +215,7 @@ public class ConfigGenerationBuildStep {
|
|||
defaultValues.put(e.getKey(), e.getValue());
|
||||
}
|
||||
// Recorded values from build time from any other source (higher ordinal then defaults, so override)
|
||||
String[] profiles = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getProfiles().toArray(String[]::new);
|
||||
List<String> profiles = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getProfiles();
|
||||
for (Map.Entry<String, String> entry : configItem.getReadResult().getRunTimeValues().entrySet()) {
|
||||
// Runtime values may contain active profiled names that override sames names in defaults
|
||||
// We need to keep the original name definition in case a different profile is used to run the app
|
||||
|
@ -244,8 +241,6 @@ public class ConfigGenerationBuildStep {
|
|||
staticMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings());
|
||||
Set<String> staticCustomizers = new HashSet<>(staticSafeServices(configCustomizers));
|
||||
staticCustomizers.add(StaticInitConfigBuilder.class.getName());
|
||||
String staticMappingsInfoClassName = "io.quarkus.runtime.generated.StaticInitMappingsInfo";
|
||||
generateMappingsInfo(generatedClass, reflectiveClass, staticMappingsInfoClassName, staticMappings);
|
||||
|
||||
generateConfigBuilder(generatedClass, reflectiveClass, CONFIG_STATIC_NAME,
|
||||
defaultValues,
|
||||
|
@ -257,7 +252,6 @@ public class ConfigGenerationBuildStep {
|
|||
staticSafeServices(configSourceFactories),
|
||||
secretKeyHandlers,
|
||||
staticSafeServices(secretKeyHandlerFactories),
|
||||
staticMappingsInfoClassName,
|
||||
staticMappings,
|
||||
staticCustomizers,
|
||||
staticInitConfigBuilders.stream().map(StaticInitConfigBuilderBuildItem::getBuilderClassName).collect(toSet()));
|
||||
|
@ -270,8 +264,6 @@ public class ConfigGenerationBuildStep {
|
|||
runTimeMappings.addAll(configItem.getReadResult().getRunTimeMappings());
|
||||
Set<String> runtimeCustomizers = new HashSet<>(configCustomizers);
|
||||
runtimeCustomizers.add(RuntimeConfigBuilder.class.getName());
|
||||
String runtimeMappingsInfoClassName = "io.quarkus.runtime.generated.RunTimeMappingsInfo";
|
||||
generateMappingsInfo(generatedClass, reflectiveClass, runtimeMappingsInfoClassName, runTimeMappings);
|
||||
|
||||
generateConfigBuilder(generatedClass, reflectiveClass, CONFIG_RUNTIME_NAME,
|
||||
defaultValues,
|
||||
|
@ -283,7 +275,6 @@ public class ConfigGenerationBuildStep {
|
|||
configSourceFactories,
|
||||
secretKeyHandlers,
|
||||
secretKeyHandlerFactories,
|
||||
runtimeMappingsInfoClassName,
|
||||
runTimeMappings,
|
||||
runtimeCustomizers,
|
||||
runTimeConfigBuilders.stream().map(RunTimeConfigBuilderBuildItem::getBuilderClassName).collect(toSet()));
|
||||
|
@ -518,66 +509,6 @@ public class ConfigGenerationBuildStep {
|
|||
return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
|
||||
}
|
||||
|
||||
private static final MethodDescriptor MAP_PUT = MethodDescriptor.ofMethod(HashMap.class,
|
||||
"put", Object.class, Object.class, Object.class);
|
||||
private static final MethodDescriptor SET_ADD = MethodDescriptor.ofMethod(HashSet.class,
|
||||
"add", boolean.class, Object.class);
|
||||
|
||||
private static void generateMappingsInfo(
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClass,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
|
||||
String className,
|
||||
Set<ConfigClassWithPrefix> mappings) {
|
||||
|
||||
try (ClassCreator classCreator = ClassCreator.builder()
|
||||
.classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true))
|
||||
.className(className)
|
||||
.setFinal(true)
|
||||
.build()) {
|
||||
|
||||
for (ConfigMappings.ConfigClassWithPrefix mapping : mappings) {
|
||||
generateMappingNames(classCreator, mapping);
|
||||
}
|
||||
|
||||
MethodCreator keys = classCreator.getMethodCreator("keys", Set.class);
|
||||
keys.setModifiers(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
|
||||
ResultHandle set = keys.checkCast(keys.newInstance(MethodDescriptor.ofConstructor(HashSet.class)), Set.class);
|
||||
for (ConfigMappings.ConfigClassWithPrefix mapping : mappings) {
|
||||
for (String key : ConfigMappings.getKeys(mapping)) {
|
||||
keys.invokeVirtualMethod(SET_ADD, set, keys.load(key));
|
||||
}
|
||||
}
|
||||
keys.returnValue(set);
|
||||
}
|
||||
|
||||
reflectiveClass.produce(ReflectiveClassBuildItem.builder(className).build());
|
||||
}
|
||||
|
||||
private static void generateMappingNames(ClassCreator classCreator, ConfigMappings.ConfigClassWithPrefix mapping) {
|
||||
MethodCreator method = classCreator.getMethodCreator(
|
||||
mapping.getKlass().getName().replaceAll("\\.", "_") + "_" + mapping.getPrefix().hashCode(), Map.class);
|
||||
method.setModifiers(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
|
||||
Map<String, Map<String, Set<String>>> properties = ConfigMappings.getNames(mapping);
|
||||
ResultHandle map = method.checkCast(
|
||||
method.newInstance(MethodDescriptor.ofConstructor(HashMap.class, int.class), method.load(properties.size())),
|
||||
Map.class);
|
||||
for (Map.Entry<String, Map<String, Set<String>>> entry : properties.entrySet()) {
|
||||
ResultHandle groups = method.checkCast(method.newInstance(MethodDescriptor.ofConstructor(HashMap.class, int.class),
|
||||
method.load(entry.getValue().size())), Map.class);
|
||||
for (Map.Entry<String, Set<String>> group : entry.getValue().entrySet()) {
|
||||
ResultHandle names = method
|
||||
.checkCast(method.newInstance(MethodDescriptor.ofConstructor(HashSet.class, int.class),
|
||||
method.load(group.getValue().size())), Set.class);
|
||||
for (String name : group.getValue()) {
|
||||
method.invokeVirtualMethod(SET_ADD, names, method.load(name));
|
||||
}
|
||||
method.invokeVirtualMethod(MAP_PUT, groups, method.load(group.getKey()), names);
|
||||
}
|
||||
method.invokeVirtualMethod(MAP_PUT, map, method.load(entry.getKey()), groups);
|
||||
}
|
||||
method.returnValue(map);
|
||||
}
|
||||
|
||||
private static final MethodDescriptor BUILDER_CUSTOMIZER = MethodDescriptor.ofMethod(SmallRyeConfigBuilderCustomizer.class,
|
||||
"configBuilder",
|
||||
void.class, SmallRyeConfigBuilder.class);
|
||||
|
@ -635,7 +566,6 @@ public class ConfigGenerationBuildStep {
|
|||
Set<String> configSourceFactories,
|
||||
Set<String> secretKeyHandlers,
|
||||
Set<String> secretKeyHandlerFactories,
|
||||
String mappingsInfoClassName,
|
||||
Set<ConfigClassWithPrefix> mappings,
|
||||
Set<String> configCustomizers,
|
||||
Set<String> configBuilders) {
|
||||
|
@ -700,13 +630,7 @@ public class ConfigGenerationBuildStep {
|
|||
for (ConfigClassWithPrefix mapping : mappings) {
|
||||
method.invokeStaticMethod(WITH_MAPPING, configBuilder, method.load(mapping.getKlass().getName()),
|
||||
method.load(mapping.getPrefix()));
|
||||
ResultHandle names = method.invokeStaticMethod(MethodDescriptor.ofMethod(mappingsInfoClassName,
|
||||
mapping.getKlass().getName().replaceAll("\\.", "_") + "_" + mapping.getPrefix().hashCode(), Map.class));
|
||||
method.invokeVirtualMethod(WITH_NAMES, configBuilder, names);
|
||||
}
|
||||
ResultHandle keys = method
|
||||
.invokeStaticMethod(MethodDescriptor.ofMethod(mappingsInfoClassName, "keys", Set.class));
|
||||
method.invokeVirtualMethod(WITH_KEYS, configBuilder, keys);
|
||||
|
||||
method.returnVoid();
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ public class RuntimeConfigBuilder implements SmallRyeConfigBuilderCustomizer {
|
|||
@Override
|
||||
public void configBuilder(final SmallRyeConfigBuilder builder) {
|
||||
new QuarkusConfigBuilderCustomizer().configBuilder(builder);
|
||||
builder.withMappingDefaults(false);
|
||||
|
||||
builder.withDefaultValue("quarkus.uuid", UUID.randomUUID().toString());
|
||||
|
||||
builder.forClassLoader(Thread.currentThread().getContextClassLoader())
|
||||
|
|
|
@ -11,7 +11,6 @@ public class StaticInitConfigBuilder implements SmallRyeConfigBuilderCustomizer
|
|||
@Override
|
||||
public void configBuilder(final SmallRyeConfigBuilder builder) {
|
||||
new QuarkusConfigBuilderCustomizer().configBuilder(builder);
|
||||
builder.withMappingDefaults(false);
|
||||
|
||||
builder.forClassLoader(Thread.currentThread().getContextClassLoader())
|
||||
.addDefaultInterceptors()
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.List;
|
|||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.smallrye.config.ConfigValue;
|
||||
import io.smallrye.config.Converters;
|
||||
import picocli.CommandLine;
|
||||
|
||||
@CommandLine.Command(name = "set")
|
||||
|
@ -46,6 +47,12 @@ public class SetConfig extends BaseConfigCommand implements Callable<Integer> {
|
|||
if (encryptionKey.getValue() != null) {
|
||||
args.add("--key=" + encryptionKey.getValue());
|
||||
}
|
||||
ConfigValue encryptionDecode = findKey(lines,
|
||||
"smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key-decode");
|
||||
if (encryptionDecode.getValue() == null
|
||||
|| !Converters.getImplicitConverter(Boolean.class).convert(encryptionDecode.getValue())) {
|
||||
args.add("--format=plain");
|
||||
}
|
||||
|
||||
int execute = new CommandLine(encrypt).execute(args.toArray(new String[] {}));
|
||||
if (execute < 0) {
|
||||
|
|
|
@ -81,7 +81,6 @@ class SetConfigTest {
|
|||
assertTrue(result.getStdout().contains("Adding foo.bar"));
|
||||
|
||||
SmallRyeConfig config = config();
|
||||
assertEquals("aes-gcm-nopadding", config.getConfigValue("foo.bar").getExtendedExpressionHandler());
|
||||
assertEquals("1234", config.getConfigValue("foo.bar").getValue());
|
||||
|
||||
String encryption = config.getRawValue("smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key");
|
||||
|
@ -93,13 +92,9 @@ class SetConfigTest {
|
|||
|
||||
config = config();
|
||||
|
||||
assertEquals("aes-gcm-nopadding", config.getConfigValue("foo.bar").getExtendedExpressionHandler());
|
||||
assertEquals("1234", config.getConfigValue("foo.bar").getValue());
|
||||
assertTrue(config.isPropertyPresent("foo.baz"));
|
||||
|
||||
// TODO - radcortez - Requires update in SmallRye Config
|
||||
//assertEquals("aes-gcm-nopadding", config.getConfigValue("foo.baz").getExtendedExpressionHandler());
|
||||
//assertEquals("5678", config.getConfigValue("foo.baz").getValue());
|
||||
assertEquals("5678", config.getConfigValue("foo.baz").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -118,14 +113,12 @@ class SetConfigTest {
|
|||
assertEquals(0, result.getExitCode());
|
||||
|
||||
SmallRyeConfig config = config();
|
||||
assertEquals("aes-gcm-nopadding", config.getConfigValue("foo.bar").getExtendedExpressionHandler());
|
||||
assertEquals("1234", config.getConfigValue("foo.bar").getValue());
|
||||
}
|
||||
|
||||
private SmallRyeConfig config() throws Exception {
|
||||
final PropertiesConfigSource propertiesConfigSource = new PropertiesConfigSource(
|
||||
PropertiesConfigSource propertiesConfigSource = new PropertiesConfigSource(
|
||||
tempDir.resolve("src/main/resources/application.properties").toUri().toURL());
|
||||
System.out.println(propertiesConfigSource.getProperties());
|
||||
return new SmallRyeConfigBuilder()
|
||||
.addDefaultInterceptors()
|
||||
.addDiscoveredSecretKeysHandlers()
|
||||
|
|
|
@ -68,9 +68,11 @@ import io.quarkus.deployment.builditem.ConfigPropertiesBuildItem;
|
|||
import io.quarkus.deployment.builditem.ConfigurationBuildItem;
|
||||
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
|
||||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
|
||||
import io.quarkus.deployment.configuration.definition.RootDefinition;
|
||||
import io.quarkus.deployment.recording.RecorderContext;
|
||||
import io.quarkus.gizmo.ResultHandle;
|
||||
import io.quarkus.hibernate.validator.spi.AdditionalConstrainedClassBuildItem;
|
||||
import io.quarkus.runtime.annotations.ConfigPhase;
|
||||
import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix;
|
||||
import io.smallrye.config.inject.ConfigProducer;
|
||||
|
@ -287,9 +289,12 @@ public class ConfigBuildStep {
|
|||
CombinedIndexBuildItem combinedIndex,
|
||||
BuildProducer<GeneratedClassBuildItem> generatedClasses,
|
||||
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses) {
|
||||
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
|
||||
BuildProducer<ConfigClassBuildItem> configClasses,
|
||||
BuildProducer<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses) {
|
||||
|
||||
processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, configClasses, MP_CONFIG_PROPERTIES_NAME);
|
||||
processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, reflectiveMethods, configClasses,
|
||||
additionalConstrainedClasses, MP_CONFIG_PROPERTIES_NAME);
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
|
@ -489,6 +494,7 @@ public class ConfigBuildStep {
|
|||
List<ConfigMappingBuildItem> configMappings,
|
||||
List<ConfigPropertiesBuildItem> configProperties) throws Exception {
|
||||
|
||||
// TODO - Register ConfigProperties during build time
|
||||
context.registerNonDefaultConstructor(
|
||||
ConfigClassWithPrefix.class.getDeclaredConstructor(Class.class, String.class),
|
||||
configClassWithPrefix -> Stream.of(configClassWithPrefix.getKlass(), configClassWithPrefix.getPrefix())
|
||||
|
|
|
@ -2,6 +2,8 @@ package io.quarkus.hibernate.validator.deployment;
|
|||
|
||||
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
|
@ -43,8 +45,10 @@ import org.jboss.jandex.ClassInfo;
|
|||
import org.jboss.jandex.CompositeIndex;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.jandex.MethodInfo;
|
||||
import org.jboss.jandex.Type;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
@ -60,6 +64,7 @@ import io.quarkus.arc.processor.BeanInfo;
|
|||
import io.quarkus.arc.processor.BuiltinScope;
|
||||
import io.quarkus.arc.processor.DotNames;
|
||||
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
|
||||
import io.quarkus.builder.item.SimpleBuildItem;
|
||||
import io.quarkus.deployment.Capabilities;
|
||||
import io.quarkus.deployment.Capability;
|
||||
import io.quarkus.deployment.Feature;
|
||||
|
@ -103,6 +108,7 @@ import io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyConfigSupport;
|
|||
import io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyReactiveViolationExceptionMapper;
|
||||
import io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyViolationExceptionMapper;
|
||||
import io.quarkus.hibernate.validator.runtime.jaxrs.ViolationReport;
|
||||
import io.quarkus.hibernate.validator.spi.AdditionalConstrainedClassBuildItem;
|
||||
import io.quarkus.hibernate.validator.spi.BeanValidationAnnotationsBuildItem;
|
||||
import io.quarkus.jaxrs.spi.deployment.AdditionalJaxRsResourceMethodAnnotationsBuildItem;
|
||||
import io.quarkus.resteasy.common.spi.ResteasyConfigBuildItem;
|
||||
|
@ -111,14 +117,14 @@ import io.quarkus.resteasy.common.spi.ResteasyJaxrsProviderBuildItem;
|
|||
import io.quarkus.resteasy.reactive.spi.ExceptionMapperBuildItem;
|
||||
import io.quarkus.runtime.LocalesBuildTimeConfig;
|
||||
import io.quarkus.runtime.configuration.ConfigBuilder;
|
||||
import io.smallrye.config.ConfigMappingLoader;
|
||||
import io.smallrye.config.ConfigMappingMetadata;
|
||||
import io.smallrye.config.ConfigValidator;
|
||||
import io.smallrye.config.SmallRyeConfigBuilder;
|
||||
import io.smallrye.config.validator.BeanValidationConfigValidator;
|
||||
|
||||
class HibernateValidatorProcessor {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(HibernateValidatorProcessor.class);
|
||||
|
||||
private static final String META_INF_VALIDATION_XML = "META-INF/validation.xml";
|
||||
|
||||
private static final DotName CONSTRAINT_VALIDATOR_FACTORY = DotName
|
||||
|
@ -168,9 +174,19 @@ class HibernateValidatorProcessor {
|
|||
void beanValidationAnnotations(
|
||||
BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
|
||||
CombinedIndexBuildItem combinedIndexBuildItem,
|
||||
Optional<AdditionalConstrainedClassesIndexBuildItem> additionalConstrainedClassesIndexBuildItem,
|
||||
BuildProducer<BeanValidationAnnotationsBuildItem> beanValidationAnnotations) {
|
||||
|
||||
IndexView indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex());
|
||||
IndexView indexView;
|
||||
|
||||
if (additionalConstrainedClassesIndexBuildItem.isPresent()) {
|
||||
// we use both indexes to support both generated beans and jars that contain no CDI beans but only Validation annotations
|
||||
// we also add the additional constrained classes
|
||||
indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex(),
|
||||
additionalConstrainedClassesIndexBuildItem.get().getIndex());
|
||||
} else {
|
||||
indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex());
|
||||
}
|
||||
|
||||
Set<DotName> constraints = new HashSet<>();
|
||||
Set<String> builtinConstraints = ConstraintHelper.getBuiltinConstraints();
|
||||
|
@ -217,19 +233,24 @@ class HibernateValidatorProcessor {
|
|||
|
||||
Set<DotName> configMappings = new HashSet<>();
|
||||
Set<DotName> configClassesToValidate = new HashSet<>();
|
||||
Map<DotName, Map<DotName, ConfigClassBuildItem>> embeddingMap = new HashMap<>();
|
||||
for (ConfigClassBuildItem configClass : configClasses) {
|
||||
for (String generatedConfigClass : configClass.getGeneratedClasses()) {
|
||||
DotName simple = DotName.createSimple(generatedConfigClass);
|
||||
configClassesToValidate.add(simple);
|
||||
}
|
||||
|
||||
for (ConfigMappingMetadata mappingsMetadata : ConfigMappingLoader
|
||||
.getConfigMappingsMetadata(configClass.getConfigClass())) {
|
||||
configMappings.add(DotName.createSimple(mappingsMetadata.getInterfaceType()));
|
||||
}
|
||||
configClass.getConfigComponentInterfaces().stream().map(DotName::createSimple)
|
||||
.forEach(cm -> {
|
||||
configMappings.add(cm);
|
||||
embeddingMap.computeIfAbsent(cm, c -> new HashMap<>())
|
||||
.putIfAbsent(configClass.getName(), configClass);
|
||||
});
|
||||
}
|
||||
|
||||
Set<DotName> constrainedConfigMappings = new HashSet<>();
|
||||
Set<String> configMappingsConstraints = new HashSet<>();
|
||||
|
||||
for (DotName consideredAnnotation : beanValidationAnnotations.getAllAnnotations()) {
|
||||
Collection<AnnotationInstance> annotationInstances = combinedIndex.getIndex().getAnnotations(consideredAnnotation);
|
||||
|
||||
|
@ -246,6 +267,7 @@ class HibernateValidatorProcessor {
|
|||
ClassInfo declaringClass = methodInfo.declaringClass();
|
||||
if (configMappings.contains(declaringClass.name())) {
|
||||
configMappingsConstraints.add(builtinConstraintCandidate);
|
||||
constrainedConfigMappings.add(declaringClass.name());
|
||||
}
|
||||
} else if (annotation.target().kind() == AnnotationTarget.Kind.TYPE) {
|
||||
AnnotationTarget target = annotation.target().asType().enclosingTarget();
|
||||
|
@ -254,12 +276,14 @@ class HibernateValidatorProcessor {
|
|||
ClassInfo declaringClass = methodInfo.declaringClass();
|
||||
if (configMappings.contains(declaringClass.name())) {
|
||||
configMappingsConstraints.add(builtinConstraintCandidate);
|
||||
constrainedConfigMappings.add(declaringClass.name());
|
||||
}
|
||||
}
|
||||
} else if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
|
||||
ClassInfo classInfo = annotation.target().asClass();
|
||||
if (configMappings.contains(classInfo.name())) {
|
||||
configMappingsConstraints.add(builtinConstraintCandidate);
|
||||
constrainedConfigMappings.add(classInfo.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +293,26 @@ class HibernateValidatorProcessor {
|
|||
return;
|
||||
}
|
||||
|
||||
// if in the tree of a ConfigMapping, there is one constraint, we register the whole tree
|
||||
// we might be able to do some more advanced surgery with Jandex evolution but for now
|
||||
// that's the best we can do
|
||||
Set<DotName> configComponentsInterfacesToRegisterForReflection = new HashSet<>();
|
||||
for (DotName constrainedConfigMapping : constrainedConfigMappings) {
|
||||
if (!embeddingMap.containsKey(constrainedConfigMapping)) {
|
||||
// should never happen but let's be safe
|
||||
continue;
|
||||
}
|
||||
|
||||
embeddingMap.get(constrainedConfigMapping).values().stream()
|
||||
.map(c -> c.getConfigComponentInterfaces())
|
||||
.flatMap(Collection::stream)
|
||||
.map(DotName::createSimple)
|
||||
.forEach(configComponentsInterfacesToRegisterForReflection::add);
|
||||
}
|
||||
reflectiveClass.produce(ReflectiveClassBuildItem.builder(
|
||||
configComponentsInterfacesToRegisterForReflection.stream().map(DotName::toString).toArray(String[]::new))
|
||||
.methods().build());
|
||||
|
||||
String builderClassName = HibernateBeanValidationConfigValidator.class.getName() + "Builder";
|
||||
try (ClassCreator classCreator = ClassCreator.builder()
|
||||
.classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true))
|
||||
|
@ -406,6 +450,7 @@ class HibernateValidatorProcessor {
|
|||
BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformers,
|
||||
BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
|
||||
CombinedIndexBuildItem combinedIndexBuildItem,
|
||||
Optional<AdditionalConstrainedClassesIndexBuildItem> additionalConstrainedClassesIndexBuildItem,
|
||||
BuildProducer<FeatureBuildItem> feature,
|
||||
BuildProducer<BeanContainerListenerBuildItem> beanContainerListener,
|
||||
BuildProducer<UnremovableBeanBuildItem> unremovableBeans,
|
||||
|
@ -418,8 +463,16 @@ class HibernateValidatorProcessor {
|
|||
|
||||
feature.produce(new FeatureBuildItem(Feature.HIBERNATE_VALIDATOR));
|
||||
|
||||
// we use both indexes to support both generated beans and jars that contain no CDI beans but only Validation annotations
|
||||
IndexView indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex());
|
||||
IndexView indexView;
|
||||
|
||||
if (additionalConstrainedClassesIndexBuildItem.isPresent()) {
|
||||
// we use both indexes to support both generated beans and jars that contain no CDI beans but only Validation annotations
|
||||
// we also add the additional constrained classes
|
||||
indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex(),
|
||||
additionalConstrainedClassesIndexBuildItem.get().getIndex());
|
||||
} else {
|
||||
indexView = CompositeIndex.create(beanArchiveIndexBuildItem.getIndex(), combinedIndexBuildItem.getIndex());
|
||||
}
|
||||
|
||||
Set<DotName> classNamesToBeValidated = new HashSet<>();
|
||||
Map<DotName, Set<SimpleMethodSignatureKey>> methodsWithInheritedValidation = new HashMap<>();
|
||||
|
@ -537,6 +590,30 @@ class HibernateValidatorProcessor {
|
|||
hibernateValidatorBuildTimeConfig)));
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
void indexAdditionalConstrainedClasses(List<AdditionalConstrainedClassBuildItem> additionalConstrainedClasses,
|
||||
BuildProducer<AdditionalConstrainedClassesIndexBuildItem> additionalConstrainedClassesIndex) {
|
||||
if (additionalConstrainedClasses.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an index with additional constrained classes
|
||||
Indexer indexer = new Indexer();
|
||||
for (AdditionalConstrainedClassBuildItem additionalConstrainedClass : additionalConstrainedClasses) {
|
||||
try {
|
||||
if (additionalConstrainedClass.isGenerated()) {
|
||||
indexer.index(new ByteArrayInputStream(additionalConstrainedClass.getBytes()));
|
||||
} else {
|
||||
indexer.indexClass(additionalConstrainedClass.getClazz());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.warnf(e, "Unable to index constrained class %s", additionalConstrainedClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
additionalConstrainedClassesIndex.produce(new AdditionalConstrainedClassesIndexBuildItem(indexer.complete()));
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
void optionalResourceBundles(BuildProducer<NativeImageResourceBundleBuildItem> resourceBundles) {
|
||||
String[] potentialHibernateValidatorResourceBundles = {
|
||||
|
@ -728,4 +805,16 @@ class HibernateValidatorProcessor {
|
|||
return Thread.currentThread().getContextClassLoader().getResource(META_INF_VALIDATION_XML) != null;
|
||||
}
|
||||
|
||||
private static final class AdditionalConstrainedClassesIndexBuildItem extends SimpleBuildItem {
|
||||
|
||||
private final IndexView index;
|
||||
|
||||
private AdditionalConstrainedClassesIndexBuildItem(IndexView index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public IndexView getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-core-deployment</artifactId>
|
||||
<artifactId>quarkus-builder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.smallrye</groupId>
|
||||
<artifactId>jandex</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package io.quarkus.hibernate.validator.spi;
|
||||
|
||||
import io.quarkus.builder.item.MultiBuildItem;
|
||||
|
||||
public final class AdditionalConstrainedClassBuildItem extends MultiBuildItem {
|
||||
|
||||
private static final byte[] EMPTY = new byte[0];
|
||||
|
||||
private final Class<?> clazz;
|
||||
private final String name;
|
||||
private final byte[] bytes;
|
||||
|
||||
private AdditionalConstrainedClassBuildItem(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
this.name = clazz.getName();
|
||||
this.bytes = EMPTY;
|
||||
}
|
||||
|
||||
private AdditionalConstrainedClassBuildItem(String name, byte[] bytes) {
|
||||
this.clazz = null;
|
||||
this.name = name;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public static AdditionalConstrainedClassBuildItem of(Class<?> clazz) {
|
||||
return new AdditionalConstrainedClassBuildItem(clazz);
|
||||
}
|
||||
|
||||
public static AdditionalConstrainedClassBuildItem of(String name, byte[] bytes) {
|
||||
return new AdditionalConstrainedClassBuildItem(name, bytes);
|
||||
}
|
||||
|
||||
public Class<?> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public boolean isGenerated() {
|
||||
return clazz == null;
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@ public class EagerSecurityFilter implements ContainerRequestFilter {
|
|||
var interceptorStorageHandle = Arc.container().instance(EagerSecurityInterceptorStorage.class);
|
||||
this.interceptorStorage = interceptorStorageHandle.isAvailable() ? interceptorStorageHandle.get() : null;
|
||||
Event<Object> event = Arc.container().beanManager().getEvent();
|
||||
// TODO - quarkus.security.events.enabled was marked as runtime, but providers are initialized during static init
|
||||
this.eventHelper = new SecurityEventHelper<>(event.select(AuthorizationSuccessEvent.class),
|
||||
event.select(AuthorizationFailureEvent.class), AUTHORIZATION_SUCCESS, AUTHORIZATION_FAILURE,
|
||||
Arc.container().beanManager(),
|
||||
|
|
|
@ -9,7 +9,7 @@ import io.smallrye.config.WithDefault;
|
|||
* Quarkus Security configuration.
|
||||
*/
|
||||
@ConfigMapping(prefix = "quarkus.security")
|
||||
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
|
||||
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
|
||||
public interface SecurityConfig {
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@ analysis_results.fields.reachable=30176
|
|||
analysis_results.fields.reachable.tolerance=3
|
||||
analysis_results.types.reflection=6585
|
||||
analysis_results.types.reflection.tolerance=3
|
||||
analysis_results.methods.reflection=4786
|
||||
analysis_results.methods.reflection=4556
|
||||
analysis_results.methods.reflection.tolerance=3
|
||||
analysis_results.fields.reflection=147
|
||||
analysis_results.fields.reflection.tolerance=3
|
||||
|
|
|
@ -9,7 +9,7 @@ analysis_results.fields.reachable=30098
|
|||
analysis_results.fields.reachable.tolerance=3
|
||||
analysis_results.types.reflection=6705
|
||||
analysis_results.types.reflection.tolerance=3
|
||||
analysis_results.methods.reflection=4893
|
||||
analysis_results.methods.reflection=4551
|
||||
analysis_results.methods.reflection.tolerance=3
|
||||
analysis_results.fields.reflection=170
|
||||
analysis_results.fields.reflection.tolerance=3
|
||||
|
|
|
@ -9,7 +9,7 @@ analysis_results.fields.reachable=27443
|
|||
analysis_results.fields.reachable.tolerance=3
|
||||
analysis_results.types.reflection=6128
|
||||
analysis_results.types.reflection.tolerance=3
|
||||
analysis_results.methods.reflection=4608
|
||||
analysis_results.methods.reflection=4374
|
||||
analysis_results.methods.reflection.tolerance=3
|
||||
analysis_results.fields.reflection=176
|
||||
analysis_results.fields.reflection.tolerance=3
|
||||
|
|
|
@ -9,7 +9,7 @@ analysis_results.fields.reachable=27389
|
|||
analysis_results.fields.reachable.tolerance=3
|
||||
analysis_results.types.reflection=6232
|
||||
analysis_results.types.reflection.tolerance=3
|
||||
analysis_results.methods.reflection=4708
|
||||
analysis_results.methods.reflection=4367
|
||||
analysis_results.methods.reflection.tolerance=3
|
||||
analysis_results.fields.reflection=201
|
||||
analysis_results.fields.reflection.tolerance=3
|
||||
|
|
|
@ -4,6 +4,9 @@ import java.util.Optional;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public interface Alias extends Named {
|
||||
@JsonProperty
|
||||
Optional<String> alias();
|
||||
|
|
|
@ -1,13 +1,136 @@
|
|||
package io.quarkus.it.smallrye.config;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Period;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import io.quarkus.arc.Unremovable;
|
||||
import io.quarkus.runtime.configuration.DurationConverter;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
import io.smallrye.config.WithConverter;
|
||||
import io.smallrye.config.WithDefault;
|
||||
import io.smallrye.config.WithName;
|
||||
import io.smallrye.config.WithParentName;
|
||||
|
||||
@Unremovable
|
||||
@ConfigMapping(prefix = "cloud")
|
||||
@Prod
|
||||
public interface Cloud {
|
||||
String host();
|
||||
|
||||
@Min(8000)
|
||||
int port();
|
||||
|
||||
@WithConverter(DurationConverter.class)
|
||||
Duration timeout();
|
||||
|
||||
@WithName("io-threads")
|
||||
int threads();
|
||||
|
||||
@WithParentName
|
||||
Server server();
|
||||
Map<String, Form> form();
|
||||
|
||||
Optional<Ssl> ssl();
|
||||
|
||||
Optional<Proxy> proxy();
|
||||
|
||||
Optional<Cors> cors();
|
||||
|
||||
Log log();
|
||||
|
||||
Info info();
|
||||
|
||||
interface Form {
|
||||
String loginPage();
|
||||
|
||||
String errorPage();
|
||||
|
||||
String landingPage();
|
||||
|
||||
Optional<String> cookie();
|
||||
|
||||
@WithDefault("1")
|
||||
List<Integer> positions();
|
||||
}
|
||||
|
||||
interface Ssl {
|
||||
int port();
|
||||
|
||||
String certificate();
|
||||
|
||||
@WithDefault("TLSv1.3,TLSv1.2")
|
||||
List<String> protocols();
|
||||
}
|
||||
|
||||
interface Proxy {
|
||||
boolean enable();
|
||||
|
||||
@Max(10)
|
||||
int timeout();
|
||||
}
|
||||
|
||||
interface Log {
|
||||
@WithDefault("false")
|
||||
boolean enabled();
|
||||
|
||||
@WithDefault(".log")
|
||||
String suffix();
|
||||
|
||||
@WithDefault("true")
|
||||
boolean rotate();
|
||||
|
||||
@WithDefault("COMMON")
|
||||
Pattern pattern();
|
||||
|
||||
Period period();
|
||||
|
||||
@Max(15)
|
||||
int days();
|
||||
|
||||
enum Pattern {
|
||||
COMMON,
|
||||
SHORT,
|
||||
COMBINED,
|
||||
LONG;
|
||||
}
|
||||
}
|
||||
|
||||
interface Cors {
|
||||
List<Origin> origins();
|
||||
|
||||
List<@Size(min = 2) String> methods();
|
||||
|
||||
interface Origin {
|
||||
@Size(min = 5)
|
||||
String host();
|
||||
|
||||
@Min(8000)
|
||||
int port();
|
||||
}
|
||||
}
|
||||
|
||||
interface Info {
|
||||
Optional<@Size(max = 3) String> name();
|
||||
|
||||
@Max(3)
|
||||
OptionalInt code();
|
||||
|
||||
Optional<List<@Size(max = 3) String>> alias();
|
||||
|
||||
Map<String, List<Admin>> admins();
|
||||
|
||||
Map<String, List<@Size(min = 8, max = 15) String>> firewall();
|
||||
|
||||
interface Admin {
|
||||
@Size(max = 4)
|
||||
String username();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import java.util.Optional;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public interface Named {
|
||||
@JsonProperty
|
||||
Optional<String> name();
|
||||
|
|
|
@ -23,7 +23,7 @@ public @interface Prod {
|
|||
class Validator implements ConstraintValidator<Prod, Cloud> {
|
||||
@Override
|
||||
public boolean isValid(final Cloud value, final ConstraintValidatorContext context) {
|
||||
return value.server().equals("prod");
|
||||
return value.host().equals("prod");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,6 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.microprofile.config.spi.Converter;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
@ -25,12 +21,12 @@ import io.smallrye.config.WithName;
|
|||
import io.smallrye.config.WithParentName;
|
||||
|
||||
@ConfigMapping(prefix = "http.server")
|
||||
@RegisterForReflection
|
||||
public interface Server extends Alias {
|
||||
@JsonProperty
|
||||
String host();
|
||||
|
||||
@JsonProperty
|
||||
@Min(8000)
|
||||
int port();
|
||||
|
||||
@JsonProperty
|
||||
|
@ -63,6 +59,7 @@ public interface Server extends Alias {
|
|||
@JsonProperty
|
||||
Info info();
|
||||
|
||||
@RegisterForReflection
|
||||
interface Form {
|
||||
@JsonProperty
|
||||
String loginPage();
|
||||
|
@ -81,15 +78,16 @@ public interface Server extends Alias {
|
|||
List<Integer> positions();
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
interface Proxy {
|
||||
@JsonProperty
|
||||
boolean enable();
|
||||
|
||||
@JsonProperty
|
||||
@Max(10)
|
||||
int timeout();
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
interface Log {
|
||||
@JsonProperty
|
||||
@WithDefault("false")
|
||||
|
@ -111,7 +109,6 @@ public interface Server extends Alias {
|
|||
Period period();
|
||||
|
||||
@JsonProperty
|
||||
@Max(15)
|
||||
int days();
|
||||
|
||||
@RegisterForReflection
|
||||
|
@ -123,44 +120,44 @@ public interface Server extends Alias {
|
|||
}
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
interface Cors {
|
||||
@JsonProperty
|
||||
List<Origin> origins();
|
||||
|
||||
@JsonProperty
|
||||
List<@Size(min = 2) String> methods();
|
||||
List<String> methods();
|
||||
|
||||
@RegisterForReflection
|
||||
interface Origin {
|
||||
@JsonProperty
|
||||
@Size(min = 5)
|
||||
String host();
|
||||
|
||||
@JsonProperty
|
||||
@Min(8000)
|
||||
int port();
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
interface Info {
|
||||
@JsonProperty
|
||||
Optional<@Size(max = 3) String> name();
|
||||
Optional<String> name();
|
||||
|
||||
@JsonProperty
|
||||
@Max(3)
|
||||
OptionalInt code();
|
||||
|
||||
@JsonProperty
|
||||
Optional<List<@Size(max = 3) String>> alias();
|
||||
Optional<List<String>> alias();
|
||||
|
||||
@JsonProperty
|
||||
Map<String, List<Admin>> admins();
|
||||
|
||||
@JsonProperty
|
||||
Map<String, List<@Size(min = 8, max = 15) String>> firewall();
|
||||
Map<String, List<String>> firewall();
|
||||
|
||||
@RegisterForReflection
|
||||
interface Admin {
|
||||
@JsonProperty
|
||||
@Size(max = 4)
|
||||
String username();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.quarkus.it.smallrye.config;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.enterprise.inject.Instance;
|
||||
|
@ -40,13 +39,6 @@ public class ServerResource {
|
|||
return Response.ok(server).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/host")
|
||||
public Response getServerHost() throws Exception {
|
||||
Method method = server.getClass().getDeclaredMethod("host");
|
||||
return Response.ok(method.invoke(server)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/properties")
|
||||
public Response getServerProperties() {
|
||||
|
|
|
@ -4,9 +4,10 @@ import java.util.List;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import io.smallrye.config.WithDefault;
|
||||
|
||||
// TODO - Add hierarchy here but requires https://github.com/smallrye/smallrye-config/pull/590
|
||||
@RegisterForReflection
|
||||
public interface Ssl {
|
||||
@JsonProperty
|
||||
int port();
|
||||
|
|
|
@ -36,7 +36,7 @@ http:
|
|||
|
||||
cloud:
|
||||
host: localhost
|
||||
port: 8080
|
||||
port: 5000
|
||||
timeout: 60s
|
||||
io-threads: 200
|
||||
|
||||
|
|
|
@ -22,6 +22,6 @@ public class AppConfigTest {
|
|||
containsString("name=app"),
|
||||
containsString("count=10"),
|
||||
containsString("alias=alias"),
|
||||
endsWith("}}"));
|
||||
endsWith("}"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,15 +47,6 @@ class ServerResourceTest {
|
|||
.body("log.period", equalTo("P1D"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void serverHost() {
|
||||
given()
|
||||
.get("/server/host")
|
||||
.then()
|
||||
.statusCode(OK.getStatusCode())
|
||||
.body(equalTo("localhost"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void properties() {
|
||||
given()
|
||||
|
@ -93,7 +84,8 @@ class ServerResourceTest {
|
|||
.get("/server/validator/{prefix}", "cloud")
|
||||
.then()
|
||||
.statusCode(OK.getStatusCode())
|
||||
.body("errors", hasSize(9))
|
||||
.body("errors", hasSize(10))
|
||||
.body("errors", hasItem("cloud.port must be greater than or equal to 8000"))
|
||||
.body("errors", hasItem("cloud.log.days must be less than or equal to 15"))
|
||||
.body("errors", hasItem("cloud.cors.origins[1].port must be greater than or equal to 8000"))
|
||||
.body("errors", hasItem("cloud.info.name size must be between 0 and 3"))
|
||||
|
|
Loading…
Reference in New Issue