Skip to content

Commit

Permalink
Merge branch 'main' into rename-security-policy-file
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfedh authored Mar 24, 2023
2 parents 2f40822 + 125f884 commit b2044c0
Show file tree
Hide file tree
Showing 67 changed files with 1,802 additions and 967 deletions.
14 changes: 12 additions & 2 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<microprofile-lra.version>2.0</microprofile-lra.version>
<microprofile-openapi.version>3.1</microprofile-openapi.version>
<smallrye-common.version>2.1.0</smallrye-common.version>
<smallrye-config.version>3.1.3</smallrye-config.version>
<smallrye-config.version>3.2.0</smallrye-config.version>
<smallrye-health.version>4.0.1</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>3.3.0</smallrye-open-api.version>
Expand Down Expand Up @@ -3809,6 +3809,11 @@
<artifactId>smallrye-config-common</artifactId>
<version>${smallrye-config.version}</version>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-core</artifactId>
<version>${smallrye-config.version}</version>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-validator</artifactId>
Expand All @@ -3826,7 +3831,12 @@
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-core</artifactId>
<artifactId>smallrye-config-source-keystore</artifactId>
<version>${smallrye-config.version}</version>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-crypto</artifactId>
<version>${smallrye-config.version}</version>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.jboss.logging.Logger;

import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
Expand All @@ -38,6 +37,7 @@
import io.quarkus.paths.PathCollection;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.util.JavaVersionUtil;
import io.smallrye.config.SmallRyeConfigProviderResolver;

public class QuarkusAugmentor {

Expand Down Expand Up @@ -177,8 +177,8 @@ public BuildResult run() throws Exception {
return buildResult;
} finally {
try {
ConfigProviderResolver.instance()
.releaseConfig(ConfigProviderResolver.instance().getConfig(deploymentClassLoader));
((SmallRyeConfigProviderResolver) SmallRyeConfigProviderResolver.instance())
.releaseConfig(deploymentClassLoader);
} catch (Exception ignore) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import io.smallrye.config.ConfigSourceInterceptor;
import io.smallrye.config.ConfigSourceInterceptorFactory;
import io.smallrye.config.ConfigValidator;
import io.smallrye.config.SecretKeysHandler;
import io.smallrye.config.SecretKeysHandlerFactory;
import io.smallrye.config.SmallRyeConfigProviderResolver;

class ConfigBuildSteps {
Expand Down Expand Up @@ -90,6 +92,8 @@ void nativeServiceProviders(
Converter.class,
ConfigSourceInterceptor.class,
ConfigSourceInterceptorFactory.class,
SecretKeysHandler.class,
SecretKeysHandlerFactory.class,
ConfigValidator.class)) {
final String serviceName = serviceClass.getName();
final Set<String> names = ServiceUtil.classNamesNamedIn(classLoader, SERVICES_PREFIX + serviceName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,8 @@ public static SmallRyeConfigBuilder configBuilder(final boolean runTime, final b
final boolean addDiscovered, final LaunchMode launchMode) {
SmallRyeConfigBuilder builder = emptyConfigBuilder();

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
builder.forClassLoader(classLoader);
builder.addDefaultSources();
builder.withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem());
builder.withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath());
builder.withSources(new DotEnvConfigSourceProvider());
if (launchMode.isDevOrTest() && (runTime || bootstrap)) {
builder.withSources(new RuntimeOverrideConfigSource(classLoader));
builder.withSources(new RuntimeOverrideConfigSource(Thread.currentThread().getContextClassLoader()));
}
if (runTime || bootstrap) {
// Validator only for runtime. We cannot use the current validator for build time (chicken / egg problem)
Expand Down Expand Up @@ -184,9 +178,16 @@ public OptionalInt getPriority() {
// Ignore unmapped quarkus properties, because properties in the same root may be split between build / runtime
builder.withMappingIgnore("quarkus.**");

builder.addDefaultInterceptors();
builder.addDiscoveredInterceptors();
builder.addDiscoveredConverters();
builder.forClassLoader(Thread.currentThread().getContextClassLoader())
.addDiscoveredConverters()
.addDefaultInterceptors()
.addDiscoveredInterceptors()
.addDiscoveredSecretKeysHandlers()
.addDefaultSources()
.withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem())
.withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath())
.withSources(new DotEnvConfigSourceProvider());

return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public SmallRyeConfig getConfigFor(final SmallRyeConfigProviderResolver configPr
//TODO: this code path is only hit when start fails in dev mode very early in the process
//the recovery code will fail without this as it cannot read any properties such as
//the HTTP port or logging info
return ConfigUtils.emptyConfigBuilder().addDefaultSources().addDiscoveredSources().build();
return ConfigUtils.emptyConfigBuilder().addDiscoveredSources().build();
}
return config;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import org.junit.jupiter.api.Test;

import io.smallrye.config.ExpressionConfigSourceInterceptor;
import io.smallrye.config.PropertiesConfigSource;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
Expand All @@ -20,11 +19,10 @@
public class ConfigExpanderTestCase {

private SmallRyeConfig buildConfig(Map<String, String> configMap) {
final SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder();
builder.withInterceptors(new ExpressionConfigSourceInterceptor());
builder.withSources(new PropertiesConfigSource(configMap, "test input", 500));
final SmallRyeConfig config = (SmallRyeConfig) builder.build();
return config;
return new SmallRyeConfigBuilder()
.addDefaultInterceptors()
.withSources(new PropertiesConfigSource(configMap, "test input", 500))
.build();
}

private Map<String, String> maps(Map... maps) {
Expand Down
87 changes: 76 additions & 11 deletions docs/src/main/asciidoc/config-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,58 @@ Then

[WARNING]
====
The configuration `quarkus.config.profile.parent` must be placed in the main `application.properties` file, passed as a system property, or passed as an environment variable.
It does not work when the configuration is placed in the profile aware files.
Do not use Profile aware files to set `quarkus.config.profile.parent`. This will not work because the profile is
required in advance to load the profile aware files.
====

=== Multiple Profiles

Multiple Profiles may be active at the same time. The configuration `quarkus.profile` accepts a comma-separated list
of profile names: `quarkus.profile=common,dev`. Both `common` and `dev` are separate profiles.

When multiple profiles are active, the rules for profile configuration are the same. If two profiles define the same
configuration, then the last listed profile has priority. Consider:

.application.properties
[source,properties]
----
quarkus.profile=common,dev
my.prop=1234
%common.my.prop=1234
%dev.my.prop=5678
%common.commom.prop=common
%dev.dev.prop=dev
%test.test.prop=test
----

Then

* `common.prop` value is `common`
* `dev.prop` value is `dev`
* `my.prop` value is `5678`
* `test.prop` does not have a `value`

It is also possible to define multiple profile properties, with a comma-separated list of profile names. If the same
property name exists in multiple profile properties then, the property name with the most specific profile wins:

.application.properties
[source,properties]
----
quarkus.profile=dev
%prod,dev.my.prop=1234
%dev.my.prop=5678
%prod,dev.another.prop=1234
----

Then

* `my.prop` value is 5678.
* `another.prop` value is 1234.

=== Default Runtime Profile

The default Quarkus runtime profile is set to the profile used to build the application:
Expand Down Expand Up @@ -475,6 +523,23 @@ application.host=${HOST:${remote.host}}
This will expand the `HOST` environment variable and use the value of the property `remote.host` as the default value
if `HOST` is not set.

== Secret Keys Expressions

A secret configuration may be expressed as `${handler::value}`, where the `handler` is the name of a
`io.smallrye.config.SecretKeysHandler` to decode or decrypt the `value`. Consider:

.application.properties
[source,properties]
----
my.secret=${aes-gcm-nopadding::DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa_kTliQBpuzTobDZxlg}
----

A lookup to `my.secret` will use the `SecretKeysHandler` name `aes-gcm-nopadding` to decode the value
`DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa_kTliQBpuzTobDZxlg`.

For more information, please check SmallRye Config
link:https://smallrye.io/smallrye-config/Main/config/secret-keys/[Secret Keys] documentation.

== Accessing a generating UUID

The default config source from Quarkus provides a random UUID value.
Expand Down Expand Up @@ -568,23 +633,23 @@ If you are in the rare situation that you need to change the build time configur
== Additional Information

* xref:config-yaml.adoc[YAML ConfigSource Extension]
// Moved to Quarkiverse. There is a redirect to resolve the link
* xref:vault.adoc[HashiCorp Vault ConfigSource Extension]
// Moved to Quarkiverse. There is a redirect to resolve the link
* xref:consul-config.adoc[Consul ConfigSource Extension]
* xref:spring-cloud-config-client.adoc[Spring Cloud ConfigSource Extension]
* xref:config-mappings.adoc[Mapping configuration to objects]
* xref:config-extending-support.adoc[Extending configuration support]

Quarkus relies on link:https://github.com/smallrye/smallrye-config/[SmallRye Config] and inherits its features:

* Additional ``ConfigSource``s
* Additional ``Converter``s
* Indexed properties
* Parent profile
* Interceptors for configuration value resolution
* Relocate configuration properties
* Fallback configuration properties
* Logging
* Hide secrets
* link:https://smallrye.io/smallrye-config/Main/config-sources/custom/[Additional Config Sources]
* link:https://smallrye.io/smallrye-config/Main/config-sources/factories/[Config Source Factories]
* link:https://smallrye.io/smallrye-config/Main/converters/custom/[Additional Converters]
* link:https://smallrye.io/smallrye-config/Main/extensions/interceptors/[Interceptors]
* link:https://smallrye.io/smallrye-config/Main/extensions/relocate/[Relocate Configuration]
* link:https://smallrye.io/smallrye-config/Main/extensions/fallback/[Fallback Configuration]
* link:https://smallrye.io/smallrye-config/Main/config/secret-keys/[Secret Keys]

For more information, please check the
link:https://smallrye.io/smallrye-config/Main[SmallRye Config documentation].
Expand Down
33 changes: 33 additions & 0 deletions docs/src/main/asciidoc/rest-client-reactive.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,39 @@ REST Client Reactive needs to know the classes used as multipart return types up

WARNING: The files you download are not automatically removed and can take up a lot of disk space. Consider removing the files when you are done working with them.

=== Multipart mixed / OData usage

It is not uncommon that an application has to interact with enterprise systems (like CRM systems) using a special protocol called https://www.odata.org/documentation/odata-version-3-0/batch-processing/[OData].
This protocol essentially uses a custom HTTP `Content-Type` which needs some glue code to work with the REST Client (creating the body is entirely up to the application - the REST Client can't do much to help).

An example looks like the following:

[source, java]
----
@Path("/crm")
@RegisterRestClient
public interface CRMService {
@POST
@ClientHeaderParam(name = "Content-Type", value = "{calculateContentType}") // <1>
String performBatch(@HeaderParam("Authorization") String accessToken, @NotBody String batchId, String body); // <2>
default String calculateContentType(ComputedParamContext context) {
return "multipart/mixed;boundary=batch_" + context.methodParameters().get(1).value(); // <3>
}
}
----

The code uses the following pieces:

<1> `@ClientHeaderParam(name = "Content-Type", value = "{calculateContentType}")` which ensures that the `Content-Type` header is created by calling the interface's `calculateContentType` default method.
<2> The aforementioned parameter needs to be annotated with `@NotBody` because it is only used to aid the construction of HTTP headers.
<3> `context.methodParameters().get(1).value()` which allows the `calculateContentType` method to obtain the proper method parameter passed to the REST Client method.


As previously mentioned, the body parameter needs to be properly crafted by the application code to conform to the service's requirements.


== Proxy support
REST Client Reactive supports sending requests through a proxy.
It honors the JVM settings for it but also allows to specify both:
Expand Down
4 changes: 4 additions & 0 deletions extensions/caffeine/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-caffeine</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-dev-ui-spi</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.quarkiverse.caffeine.deployment.devui;

import java.io.InputStream;
import java.net.URL;
import java.util.jar.Manifest;

import com.github.benmanes.caffeine.cache.Caffeine;

import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.devui.spi.page.CardPageBuildItem;
import io.quarkus.devui.spi.page.Page;
import io.quarkus.devui.spi.page.PageBuilder;

/**
* Dev UI card for displaying important details such as the Caffeine library version.
*/
public class CaffeineDevUIProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
void createCard(BuildProducer<CardPageBuildItem> cardPageBuildItemBuildProducer) {
final CardPageBuildItem card = new CardPageBuildItem("Caffeine");

final PageBuilder versionPage = Page.externalPageBuilder("Version")
.icon("font-awesome-solid:mug-hot")
.url("https://github.com/ben-manes/caffeine")
.doNotEmbed()
.staticLabel(getManifest(Caffeine.class).getMainAttributes().getValue("Bundle-Version"));
card.addPage(versionPage);

card.setCustomCard("qwc-caffeine-card.js");

cardPageBuildItemBuildProducer.produce(card);
}

public static Manifest getManifest(Class<?> clz) {
String resource = "/" + clz.getName().replace(".", "/") + ".class";
String fullPath = clz.getResource(resource).toString();
String archivePath = fullPath.substring(0, fullPath.length() - resource.length());

try (InputStream input = new URL(archivePath + "/META-INF/MANIFEST.MF").openStream()) {
return new Manifest(input);
} catch (Exception e) {
throw new RuntimeException("Loading MANIFEST for class " + clz + " failed!", e);
}
}
}
Loading

0 comments on commit b2044c0

Please sign in to comment.