use of io.smallrye.config.ConfigMappings.ConfigClassWithPrefix in project quarkus by quarkusio.
the class ExtensionLoader method loadStepsFrom.
/**
* Load all the build steps from the given class loader.
*
* @param classLoader the class loader
* @param buildSystemProps the build system properties to use
* @param launchMode launch mode
* @param configCustomizer configuration customizer
* @return a consumer which adds the steps to the given chain builder
* @throws IOException if the class loader could not load a resource
* @throws ClassNotFoundException if a build step class is not found
*/
public static Consumer<BuildChainBuilder> loadStepsFrom(ClassLoader classLoader, Properties buildSystemProps, ApplicationModel appModel, LaunchMode launchMode, DevModeType devModeType) throws IOException, ClassNotFoundException {
// populate with all known types
List<Class<?>> roots = new ArrayList<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
final ConfigRoot annotation = clazz.getAnnotation(ConfigRoot.class);
if (annotation == null) {
cfgLog.warnf("Ignoring configuration root %s because it has no annotation", clazz);
} else {
roots.add(clazz);
}
}
final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(roots);
// now prepare & load the build configuration
final SmallRyeConfigBuilder builder = ConfigUtils.configBuilder(false, launchMode);
final DefaultValuesConfigurationSource ds1 = new DefaultValuesConfigurationSource(reader.getBuildTimePatternMap());
final DefaultValuesConfigurationSource ds2 = new DefaultValuesConfigurationSource(reader.getBuildTimeRunTimePatternMap());
final PropertiesConfigSource pcs = new PropertiesConfigSource(buildSystemProps, "Build system");
final Map<String, String> platformProperties = appModel.getPlatformProperties();
if (platformProperties.isEmpty()) {
builder.withSources(ds1, ds2, pcs);
} else {
final KeyMap<String> props = new KeyMap<>(platformProperties.size());
for (Map.Entry<String, String> prop : platformProperties.entrySet()) {
props.findOrAdd(new NameIterator(prop.getKey())).putRootValue(prop.getValue());
}
final KeyMapBackedConfigSource platformConfigSource = new KeyMapBackedConfigSource("Quarkus platform", // (see io.quarkus.deployment.configuration.DefaultValuesConfigurationSource)
Integer.MIN_VALUE + 1000, props);
builder.withSources(ds1, ds2, platformConfigSource, pcs);
}
for (ConfigClassWithPrefix mapping : reader.getBuildTimeVisibleMappings()) {
builder.withMapping(mapping.getKlass(), mapping.getPrefix());
}
final SmallRyeConfig src = builder.build();
// install globally
QuarkusConfigFactory.setConfig(src);
final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
try {
cpr.releaseConfig(cpr.getConfig());
} catch (IllegalStateException ignored) {
// just means no config was installed, which is fine
}
final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src);
final BooleanSupplierFactoryBuildItem bsf = new BooleanSupplierFactoryBuildItem(readResult, launchMode, devModeType);
Consumer<BuildChainBuilder> result = Functions.discardingConsumer();
// BooleanSupplier factory
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(bsf);
}).produces(BooleanSupplierFactoryBuildItem.class).build());
// the proxy objects used for run time config in the recorders
Map<Class<?>, Object> proxies = new HashMap<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, "META-INF/quarkus-build-steps.list")) {
try {
result = result.andThen(ExtensionLoader.loadStepsFromClass(clazz, readResult, proxies, bsf));
} catch (Throwable e) {
throw new RuntimeException("Failed to load steps from " + clazz, e);
}
}
// this has to be an identity hash map else the recorder will get angry
Map<Object, FieldDescriptor> rootFields = new IdentityHashMap<>();
Map<Object, ConfigClassWithPrefix> mappingClasses = new IdentityHashMap<>();
for (Map.Entry<Class<?>, Object> entry : proxies.entrySet()) {
// ConfigRoot
RootDefinition root = readResult.getAllRootsByClass().get(entry.getKey());
if (root != null) {
rootFields.put(entry.getValue(), root.getDescriptor());
continue;
}
// ConfigMapping
ConfigClassWithPrefix mapping = readResult.getAllMappings().get(entry.getKey());
if (mapping != null) {
mappingClasses.put(entry.getValue(), mapping);
continue;
}
throw new IllegalStateException("No config found for " + entry.getKey());
}
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(new ConfigurationBuildItem(readResult));
bc.produce(new RunTimeConfigurationProxyBuildItem(proxies));
ObjectLoader rootLoader = new ObjectLoader() {
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
return body.readStaticField(rootFields.get(obj));
}
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return rootFields.containsKey(obj);
}
};
ObjectLoader mappingLoader = new ObjectLoader() {
@Override
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
ConfigClassWithPrefix mapping = mappingClasses.get(obj);
MethodDescriptor getConfig = MethodDescriptor.ofMethod(ConfigProvider.class, "getConfig", Config.class);
ResultHandle config = body.invokeStaticMethod(getConfig);
MethodDescriptor getMapping = MethodDescriptor.ofMethod(SmallRyeConfig.class, "getConfigMapping", Object.class, Class.class, String.class);
return body.invokeVirtualMethod(getMapping, config, body.loadClass(mapping.getKlass()), body.load(mapping.getPrefix()));
}
@Override
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return mappingClasses.containsKey(obj);
}
};
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(rootLoader));
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(mappingLoader));
}).produces(ConfigurationBuildItem.class).produces(RunTimeConfigurationProxyBuildItem.class).produces(BytecodeRecorderObjectLoaderBuildItem.class).build());
return result;
}
use of io.smallrye.config.ConfigMappings.ConfigClassWithPrefix in project quarkus by quarkusio.
the class ConfigGenerationBuildStep method extensionMappings.
@BuildStep
void extensionMappings(ConfigurationBuildItem configItem, CombinedIndexBuildItem combinedIndex, BuildProducer<GeneratedClassBuildItem> generatedClasses, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses, BuildProducer<ConfigClassBuildItem> configClasses) {
List<ConfigClassWithPrefix> buildTimeRunTimeMappings = configItem.getReadResult().getBuildTimeRunTimeMappings();
for (ConfigClassWithPrefix buildTimeRunTimeMapping : buildTimeRunTimeMappings) {
processExtensionConfigMapping(buildTimeRunTimeMapping.getKlass(), buildTimeRunTimeMapping.getPrefix(), combinedIndex, generatedClasses, reflectiveClasses, configClasses);
}
final List<ConfigClassWithPrefix> runTimeMappings = configItem.getReadResult().getRunTimeMappings();
for (ConfigClassWithPrefix runTimeMapping : runTimeMappings) {
processExtensionConfigMapping(runTimeMapping.getKlass(), runTimeMapping.getPrefix(), combinedIndex, generatedClasses, reflectiveClasses, configClasses);
}
}
use of io.smallrye.config.ConfigMappings.ConfigClassWithPrefix in project quarkus by quarkusio.
the class ConfigDescriptionBuildStep method processMappings.
private void processMappings(List<ConfigClassWithPrefix> mappings, List<ConfigDescriptionBuildItem> descriptionBuildItems, Properties javaDocProperties, ConfigPhase configPhase) {
for (ConfigClassWithPrefix mapping : mappings) {
Map<String, Property> properties = ConfigMappings.getProperties(mapping);
for (Map.Entry<String, Property> entry : properties.entrySet()) {
String propertyName = entry.getKey();
Property property = entry.getValue();
Method method = property.getMethod();
String defaultValue = null;
if (property instanceof PrimitiveProperty) {
PrimitiveProperty primitiveProperty = (PrimitiveProperty) property;
if (primitiveProperty.hasDefaultValue()) {
defaultValue = primitiveProperty.getDefaultValue();
} else if (primitiveProperty.getPrimitiveType() == boolean.class) {
defaultValue = "false";
} else if (primitiveProperty.getPrimitiveType() != char.class) {
defaultValue = "0";
}
} else if (property instanceof LeafProperty) {
LeafProperty leafProperty = (LeafProperty) property;
if (leafProperty.hasDefaultValue()) {
defaultValue = leafProperty.getDefaultValue();
}
}
String javadocKey = method.getDeclaringClass().getName().replace('$', '.') + '.' + method.getName();
// TODO - radcortez - Fix nulls
descriptionBuildItems.add(new ConfigDescriptionBuildItem(propertyName, defaultValue, javaDocProperties.getProperty(javadocKey), null, null, configPhase));
}
}
}
use of io.smallrye.config.ConfigMappings.ConfigClassWithPrefix in project smallrye-config by smallrye.
the class ConfigExtension method validate.
protected void validate(@Observes AfterDeploymentValidation adv) {
Config config = ConfigProvider.getConfig(getContextClassLoader());
Set<String> configNames = StreamSupport.stream(config.getPropertyNames().spliterator(), false).collect(toSet());
for (InjectionPoint injectionPoint : getConfigPropertyInjectionPoints()) {
Type type = injectionPoint.getType();
// We don't validate the Optional / Provider / Supplier / ConfigValue for defaultValue.
if (type instanceof Class && org.eclipse.microprofile.config.ConfigValue.class.isAssignableFrom((Class<?>) type) || type instanceof Class && OptionalInt.class.isAssignableFrom((Class<?>) type) || type instanceof Class && OptionalLong.class.isAssignableFrom((Class<?>) type) || type instanceof Class && OptionalDouble.class.isAssignableFrom((Class<?>) type) || type instanceof ParameterizedType && (Optional.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()) || Provider.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()) || Supplier.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()))) {
continue;
}
ConfigProperty configProperty = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class);
String name;
try {
name = ConfigProducerUtil.getConfigKey(injectionPoint, configProperty);
} catch (IllegalStateException e) {
adv.addDeploymentProblem(InjectionMessages.msg.retrieveConfigFailure(null, formatInjectionPoint(injectionPoint), e.getLocalizedMessage(), e));
continue;
}
// Finally also check if the property is indexed (might be a Collection with indexed properties).
if ((!configNames.contains(name) && ConfigProducerUtil.getRawValue(name, config) == null) && !isMap(type) && !isIndexed(type, name, config)) {
if (configProperty.defaultValue().equals(ConfigProperty.UNCONFIGURED_VALUE)) {
adv.addDeploymentProblem(InjectionMessages.msg.noConfigValue(name, formatInjectionPoint(injectionPoint)));
continue;
}
}
try {
// Check if the value can be injected. This may cause duplicated config reads (to validate and to inject).
ConfigProducerUtil.getValue(injectionPoint, config);
} catch (Exception e) {
adv.addDeploymentProblem(InjectionMessages.msg.retrieveConfigFailure(name, formatInjectionPoint(injectionPoint), e.getLocalizedMessage(), e));
}
}
Set<ConfigClassWithPrefix> configMappingsWithPrefix = mapToConfigObjectWithPrefix(configMappings, configMappingInjectionPoints);
Set<ConfigClassWithPrefix> configPropertiesWithPrefix = mapToConfigObjectWithPrefix(configProperties, configPropertiesInjectionPoints);
try {
registerConfigMappings(config.unwrap(SmallRyeConfig.class), configMappingsWithPrefix);
registerConfigProperties(config.unwrap(SmallRyeConfig.class), configPropertiesWithPrefix);
} catch (ConfigValidationException e) {
adv.addDeploymentProblem(e);
}
}
Aggregations