diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/multipart/MultipartEncoderModeTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/multipart/MultipartEncoderModeTest.java new file mode 100644 index 0000000000000..62f18083af66f --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/multipart/MultipartEncoderModeTest.java @@ -0,0 +1,94 @@ +package io.quarkus.rest.client.reactive.multipart; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.net.URI; + +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.FormParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.jboss.resteasy.reactive.ResponseStatus; +import org.jboss.resteasy.reactive.RestForm; +import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties; +import org.jboss.resteasy.reactive.client.impl.multipart.PausableHttpPostRequestEncoder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.common.http.TestHTTPResource; + +public class MultipartEncoderModeTest { + @TestHTTPResource + URI baseUri; + + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest() + .withApplicationRoot(jar -> jar.addClasses(Resource.class, Client.class)) + .withConfigurationResource("multipart-encoder-mode-test.properties"); + + @Inject + @RestClient + Client client; + + @Test + void shouldPassUsingCustomMultipartPostEncoderMode(@TempDir File tempDir) throws IOException { + File file = File.createTempFile("MultipartTest", ".txt", tempDir); + assertThat(client.upload(file)).isEqualTo("OK"); + } + + /** + * This filter is present to check in advance if property {@link QuarkusRestClientProperties#MULTIPART_ENCODER_MODE} + * is of the right type. + */ + static class MultipartEncoderModeCheck implements ClientRequestFilter { + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + Object mode = requestContext.getConfiguration().getProperty(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE); + if (mode == null) { + requestContext.abortWith(Response.serverError().entity("encoderMode is null").build()); + return; + } + if (mode.getClass() != PausableHttpPostRequestEncoder.EncoderMode.class) { + requestContext.abortWith(Response.serverError().entity("encoderMode illegal type").build()); + return; + } + } + } + + @Path("resource") + static public class Resource { + @Path("upload") + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @ResponseStatus(200) + public String upload(@RestForm File file) { + return "OK"; + } + } + + @Path("resource") + @RegisterRestClient(configKey = "client") + @RegisterProvider(MultipartEncoderModeCheck.class) + static public interface Client { + @Path("upload") + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + String upload(@FormParam("file") File file); + } +} diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/multipart-encoder-mode-test.properties b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/multipart-encoder-mode-test.properties new file mode 100644 index 0000000000000..8b0eef3890109 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/multipart-encoder-mode-test.properties @@ -0,0 +1,2 @@ +quarkus.rest-client.multipart-post-encoder-mode=HTML5 +quarkus.rest-client.client.url=http://localhost:${quarkus.http.test-port} \ No newline at end of file diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java index e6966a2ffae71..e10be163fb08b 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java @@ -23,8 +23,8 @@ import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties; +import org.jboss.resteasy.reactive.client.impl.multipart.PausableHttpPostRequestEncoder; -import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder; import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.restclient.config.RestClientConfig; import io.quarkus.restclient.config.RestClientsConfig; @@ -77,7 +77,7 @@ void configureBuilder(QuarkusRestClientBuilder builder) { private void configureCustomProperties(QuarkusRestClientBuilder builder) { Optional encoder = configRoot.multipartPostEncoderMode; if (encoder != null && encoder.isPresent()) { - HttpPostRequestEncoder.EncoderMode mode = HttpPostRequestEncoder.EncoderMode + PausableHttpPostRequestEncoder.EncoderMode mode = PausableHttpPostRequestEncoder.EncoderMode .valueOf(encoder.get().toUpperCase(Locale.ROOT)); builder.property(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE, mode); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java index 10948c051213d..6f72c3b6ded94 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java @@ -20,12 +20,12 @@ import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties; +import org.jboss.resteasy.reactive.client.impl.multipart.PausableHttpPostRequestEncoder; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder; import io.quarkus.restclient.config.RestClientConfig; import io.quarkus.restclient.config.RestClientMultipartConfig; import io.quarkus.restclient.config.RestClientsConfig; @@ -99,7 +99,7 @@ public void testClientSpecificConfigs() { Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.SHARED, true); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.NAME, "my-client"); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE, - HttpPostRequestEncoder.EncoderMode.HTML5); + PausableHttpPostRequestEncoder.EncoderMode.HTML5); Mockito.verify(restClientBuilderMock).proxyAddress("host1", 123); Mockito.verify(restClientBuilderMock).proxyUser("proxyUser1"); @@ -141,7 +141,7 @@ public void testGlobalConfigs() { Mockito.verify(restClientBuilderMock).baseUri(URI.create("http://localhost:8080")); Mockito.verify(restClientBuilderMock) - .property(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE, HttpPostRequestEncoder.EncoderMode.HTML5); + .property(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE, PausableHttpPostRequestEncoder.EncoderMode.HTML5); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.DISABLE_CONTEXTUAL_ERROR_MESSAGES, true); Mockito.verify(restClientBuilderMock).proxyAddress("host2", 123); diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java index 8783a86417535..e4e16d0682b1c 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java @@ -27,7 +27,7 @@ public class QuarkusRestClientProperties { public static final String READ_TIMEOUT = "io.quarkus.rest.client.read-timeout"; /** - * See {@link io.netty.handler.codec.http.multipart.HttpPostRequestEncoder.EncoderMode}, RFC1738 by default + * See {@link EncoderMode}, RFC1738 by default */ public static final String MULTIPART_ENCODER_MODE = "io.quarkus.rest.client.multipart-post-encoder-mode";