Skip to content

Commit

Permalink
feat: add new config values, allowing to specify file- and memory thr…
Browse files Browse the repository at this point in the history
…eshold settings for multipart requests of a client builder
  • Loading branch information
mzellho committed Feb 27, 2025
1 parent f8ab86d commit 32a20b0
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,19 @@ interface RestClientMultipartConfig {
*/
@Deprecated
Optional<Integer> maxChunkSize();

/**
* The threshold to use for the amount of data to store in memory for entities, up to {@code Long.MAX_VALUE}. See
* {@code dev.resteasy.entity.memory.threshold} in RESTEasy documentation.
*/
Optional<MemorySize> memoryThreshold();

/**
* The threshold to use for the amount of data that can be stored in a file for entities. If the threshold is reached an
* IllegalStateException will be thrown. A value of -1 means no limit, up to {@code Long.MAX_VALUE}. See
* {@code dev.resteasy.entity.file.threshold } in RESTEasy documentation.
*/
Optional<MemorySize> fileThreshold();
}

interface RestClientConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.quarkus.restclient.config.key.SharedThreeConfigKeyRestClient;
import io.quarkus.restclient.config.key.SharedTwoConfigKeyRestClient;
import io.quarkus.runtime.configuration.ConfigUtils;
import io.quarkus.runtime.configuration.MemorySizeConverter;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SmallRyeConfigBuilderCustomizer;
Expand Down Expand Up @@ -371,5 +372,9 @@ private void verifyConfig(RestClientConfig config) {
assertThat(config.connectionPoolSize().get()).isEqualTo(10);
assertTrue(config.maxChunkSize().isPresent());
assertThat(config.maxChunkSize().get().asBigInteger()).isEqualTo(BigInteger.valueOf(1024));
assertThat(config.multipart().fileThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("5M").asBigInteger());
assertThat(config.multipart().memoryThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("10M").asBigInteger());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".hostname-v
quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".connection-ttl=30000
quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".connection-pool-size=10
quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".max-chunk-size=1024
quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".multipart.file-threshold=5M
quarkus.rest-client."io.quarkus.restclient.config.FullNameRestClient".multipart.memory-threshold=10M

quarkus.rest-client.key.removes-trailing-slash=false
quarkus.rest-client.key.url=http://localhost:8080
Expand All @@ -29,6 +31,8 @@ quarkus.rest-client.key.hostname-verifier=io.quarkus.restclient.configuration.My
quarkus.rest-client.key.connection-ttl=30000
quarkus.rest-client.key.connection-pool-size=10
quarkus.rest-client.key.max-chunk-size=1024
quarkus.rest-client.key.multipart.file-threshold=5M
quarkus.rest-client.key.multipart.memory-threshold=10M

quarkus.rest-client."io.quarkus.restclient.config.MPRestClient".url=http://localhost:8080
io.quarkus.restclient.config.MPRestClient/mp-rest/url=http://localhost:8081
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.quarkus.arc.Arc;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.runtime.configuration.MemorySizeConverter;
import io.quarkus.test.QuarkusUnitTest;

public class GlobalConfigurationTest {
Expand Down Expand Up @@ -79,5 +80,9 @@ void checkGlobalConfigValues() {
assertThat(configRoot.keyStore().get()).isEqualTo("/path");
assertThat(configRoot.keyStorePassword().get()).isEqualTo("password");
assertThat(configRoot.keyStoreType().get()).isEqualTo("JKS");
assertThat(configRoot.multipart().fileThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("5M").asBigInteger());
assertThat(configRoot.multipart().memoryThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("10M").asBigInteger());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.quarkus.restclient.NoopHostnameVerifier;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.restclient.config.RestClientsConfig.RestClientConfig;
import io.quarkus.runtime.configuration.MemorySize;
import io.smallrye.config.SmallRyeConfig;

public class RestClientBase {
Expand Down Expand Up @@ -92,6 +93,20 @@ protected void configureCustomProperties(RestClientBuilder builder) {
builder.property("resteasy.connectionTTL",
Arrays.asList(connectionTTL.get(), TimeUnit.MILLISECONDS));
}

Optional<MemorySize> fileThreshold = oneOf(restClientConfig.multipart().fileThreshold(),
configRoot.multipart().fileThreshold());
if (fileThreshold.isPresent()) {
builder.property("dev.resteasy.entity.file.threshold",
fileThreshold.get().asLongValue());
}

Optional<MemorySize> memoryThreshold = oneOf(restClientConfig.multipart().memoryThreshold(),
configRoot.multipart().memoryThreshold());
if (memoryThreshold.isPresent()) {
builder.property("dev.resteasy.entity.memory.threshold",
memoryThreshold.get().asLongValue());
}
}

protected void configureProxy(RestClientBuilder builder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.quarkus.arc.Arc;
import io.quarkus.rest.client.reactive.configuration.EchoResource;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.runtime.configuration.MemorySizeConverter;
import io.quarkus.test.QuarkusUnitTest;

class ConfigurationTest {
Expand Down Expand Up @@ -91,6 +92,10 @@ private void verifyClientConfig(RestClientsConfig.RestClientConfig clientConfig,
assertThat(clientConfig.followRedirects().get()).isEqualTo(true);
assertTrue(clientConfig.queryParamStyle().isPresent());
assertThat(clientConfig.queryParamStyle().get()).isEqualTo(QueryParamStyle.COMMA_SEPARATED);
assertThat(clientConfig.multipart().fileThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("5M").asBigInteger());
assertThat(clientConfig.multipart().memoryThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("10M").asBigInteger());

if (checkExtraProperties) {
assertTrue(clientConfig.connectionTTL().isPresent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.quarkus.arc.Arc;
import io.quarkus.rest.client.reactive.configuration.EchoResource;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.runtime.configuration.MemorySizeConverter;
import io.quarkus.test.QuarkusUnitTest;

public class GlobalConfigurationTest {
Expand Down Expand Up @@ -78,5 +79,9 @@ void checkGlobalConfigValues() {
assertThat(configRoot.keyStore().get()).isEqualTo("/path");
assertThat(configRoot.keyStorePassword().get()).isEqualTo("password");
assertThat(configRoot.keyStoreType().get()).isEqualTo("JKS");
assertThat(configRoot.multipart().fileThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("5M").asBigInteger());
assertThat(configRoot.multipart().memoryThreshold().get().asBigInteger())
.isEqualTo(new MemorySizeConverter().convert("10M").asBigInteger());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.quarkus.arc.InstanceHandle;
import io.quarkus.rest.client.reactive.runtime.ProxyAddressUtil.HostAndPort;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.runtime.configuration.MemorySize;
import io.quarkus.tls.TlsConfiguration;
import io.smallrye.config.SmallRyeConfig;
import io.vertx.core.net.KeyCertOptions;
Expand Down Expand Up @@ -527,6 +528,24 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi
clientBuilder.maxChunkSize(DEFAULT_MAX_CHUNK_SIZE);
}

MemorySize fileThreshold = (MemorySize) getConfiguration()
.getProperty(QuarkusRestClientProperties.MULTIPART_FILE_THRESHOLD);
if (fileThreshold != null) {
property("dev.resteasy.entity.file.threshold", fileThreshold.asLongValue());
} else if (restClients.multipart().fileThreshold().isPresent()) {
property("dev.resteasy.entity.file.threshold",
restClients.multipart().fileThreshold().get().asLongValue());
}

MemorySize memoryThreshold = (MemorySize) getConfiguration()
.getProperty(QuarkusRestClientProperties.MULTIPART_MEMORY_THRESHOLD);
if (memoryThreshold != null) {
property("dev.resteasy.entity.memory.threshold", memoryThreshold.asLongValue());
} else if (restClients.multipart().memoryThreshold().isPresent()) {
property("dev.resteasy.entity.memory.threshold",
restClients.multipart().memoryThreshold().get().asLongValue());
}

if (getConfiguration().hasProperty(QuarkusRestClientProperties.HTTP2)) {
clientBuilder.http2((Boolean) getConfiguration().getProperty(QuarkusRestClientProperties.HTTP2));
} else if (restClients.http2()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ private void configureCustomProperties(QuarkusRestClientBuilder builder) {
configRoot.multipart().maxChunkSize());
builder.property(QuarkusRestClientProperties.MAX_CHUNK_SIZE, maxChunkSize.orElse(DEFAULT_MAX_CHUNK_SIZE));

Optional<MemorySize> fileThreshold = oneOf(restClientConfig.multipart().fileThreshold(),
configRoot.multipart().fileThreshold());
if (fileThreshold.isPresent()) {
builder.property("dev.resteasy.entity.file.threshold",
fileThreshold.get().asLongValue());
}

Optional<MemorySize> memoryThreshold = oneOf(restClientConfig.multipart().memoryThreshold(),
configRoot.multipart().memoryThreshold());
if (memoryThreshold.isPresent()) {
builder.property("dev.resteasy.entity.memory.threshold",
memoryThreshold.get().asLongValue());
}

Optional<Boolean> enableCompressions = oneOf(restClientConfig.enableCompression(), configRoot.enableCompression());
if (enableCompressions.isPresent()) {
builder.enableCompression(enableCompressions.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import io.quarkus.restclient.config.RegisteredRestClient;
import io.quarkus.restclient.config.RestClientsConfig;
import io.quarkus.runtime.configuration.ConfigUtils;
import io.quarkus.runtime.configuration.MemorySizeConverter;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SmallRyeConfigBuilderCustomizer;

Expand Down Expand Up @@ -143,6 +144,10 @@ public List<RegisteredRestClient> getRestClients() {
verify(restClientBuilderMock).property(KEEP_ALIVE_ENABLED, false);
verify(restClientBuilderMock).property(MAX_REDIRECTS, 104);
verify(restClientBuilderMock).property(MAX_CHUNK_SIZE, 1024);
verify(restClientBuilderMock).property("dev.resteasy.entity.file.threshold",
new MemorySizeConverter().convert("50M").asLongValue());
verify(restClientBuilderMock).property("dev.resteasy.entity.memory.threshold",
new MemorySizeConverter().convert("100M").asLongValue());
verify(restClientBuilderMock).followRedirects(true);
verify(restClientBuilderMock).register(MyResponseFilter1.class);
verify(restClientBuilderMock).queryParamStyle(COMMA_SEPARATED);
Expand Down Expand Up @@ -197,6 +202,10 @@ public List<RegisteredRestClient> getRestClients() {
verify(restClientBuilderMock).property(KEEP_ALIVE_ENABLED, true);
verify(restClientBuilderMock).property(MAX_REDIRECTS, 204);
verify(restClientBuilderMock).property(MAX_CHUNK_SIZE, 1024);
verify(restClientBuilderMock).property("dev.resteasy.entity.file.threshold",
new MemorySizeConverter().convert("5M").asLongValue());
verify(restClientBuilderMock).property("dev.resteasy.entity.memory.threshold",
new MemorySizeConverter().convert("10M").asLongValue());
verify(restClientBuilderMock).followRedirects(true);
verify(restClientBuilderMock).register(MyResponseFilter2.class);
verify(restClientBuilderMock).queryParamStyle(MULTI_PAIRS);
Expand Down Expand Up @@ -224,6 +233,8 @@ private static Map<String, String> createSampleConfigRoot() {
rootConfig.put("quarkus.rest-client.keep-alive-enabled", "true");
rootConfig.put("quarkus.rest-client.max-redirects", "204");
rootConfig.put("quarkus.rest-client.multipart-max-chunk-size", "1024");
rootConfig.put("quarkus.rest-client.multipart.file-threshold", "5M");
rootConfig.put("quarkus.rest-client.multipart.memory-threshold", "10M");
rootConfig.put("quarkus.rest-client.follow-redirects", "true");
rootConfig.put("quarkus.rest-client.max-chunk-size", "1024");
rootConfig.put("quarkus.rest-client.providers",
Expand Down Expand Up @@ -260,6 +271,8 @@ private static Map<String, String> createSampleClientConfig(final String restCli
clientConfig.put("quarkus.rest-client." + restClientName + ".max-redirects", "104");
clientConfig.put("quarkus.rest-client." + restClientName + ".follow-redirects", "true");
clientConfig.put("quarkus.rest-client." + restClientName + ".max-chunk-size", "1024");
clientConfig.put("quarkus.rest-client." + restClientName + ".multipart.file-threshold", "50M");
clientConfig.put("quarkus.rest-client." + restClientName + ".multipart.memory-threshold", "100M");
clientConfig.put("quarkus.rest-client." + restClientName + ".providers",
"io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilderTest$MyResponseFilter1");
clientConfig.put("quarkus.rest-client." + restClientName + ".query-param-style", "comma-separated");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ public class QuarkusRestClientProperties {
*/
public static final String MAX_CHUNK_SIZE = "io.quarkus.rest.client.max-chunk-size";

/**
* Configure the threshold to use for the amount of data to store in memory for entities.
*/
public static final String MULTIPART_FILE_THRESHOLD = "io.quarkus.rest.client.multipart.file-threshold";
/**
* Configure the threshold to use for the amount of data that can be stored in a file for entities.
*/
public static final String MULTIPART_MEMORY_THRESHOLD = "io.quarkus.rest.client.multipart.memory-threshold";

/**
* Configure the connect timeout in ms.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ multipart-client/mp-rest/url=${test.url}
multipart-chunks-client/mp-rest/url=${test.url}

quarkus.rest-client.multipart-chunks-client.max-chunk-size=1000
quarkus.rest-client.multipart-chunks-client.multipart.file-threshold=5M
quarkus.rest-client.multipart-chunks-client.multipart.memory-threshold=10M

quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true
quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true

0 comments on commit 32a20b0

Please sign in to comment.