Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow using the annotation @PartFilename on method parameters #32099

Merged
merged 1 commit into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.rest.client.reactive.multipart;

import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.BufferedReader;
Expand All @@ -25,6 +26,7 @@
import org.jboss.resteasy.reactive.MultipartForm;
import org.jboss.resteasy.reactive.PartFilename;
import org.jboss.resteasy.reactive.PartType;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand All @@ -35,6 +37,10 @@

public class MultipartFilenameTest {

public static final String FILE_NAME = "clientFile";
public static final String FILE_CONTENT = "file content";
public static final String EXPECTED_OUTPUT = FILE_NAME + ":" + FILE_CONTENT;

@TestHTTPResource
URI baseUri;

Expand Down Expand Up @@ -63,88 +69,106 @@ void shouldUseFileNameFromAnnotation() throws IOException {

ClientFormUsingFile form = new ClientFormUsingFile();
form.file = file;
assertThat(client.postMultipartWithPartFilename(form)).isEqualTo(ClientFormUsingFile.FILE_NAME);
// Using a Multipart bean
assertThat(client.postMultipartWithPartFilename(form)).isEqualTo(FILE_NAME);
// Using a field form param
assertThat(client.postMultipartWithPartFilename(file)).isEqualTo(FILE_NAME);
}

@Test
void shouldUseFileNameFromAnnotationUsingString() {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

ClientFormUsingString form = new ClientFormUsingString();
form.file = "file content";
assertThat(client.postMultipartWithPartFilenameUsingString(form)).isEqualTo("clientFile:file content");
form.file = FILE_CONTENT;
// Using a Multipart bean
assertThat(client.postMultipartWithPartFilenameUsingString(form)).isEqualTo(EXPECTED_OUTPUT);
// Using a field form param
assertThat(client.postMultipartWithPartFilenameUsingString(FILE_CONTENT)).isEqualTo(EXPECTED_OUTPUT);
}

@Test
void shouldUseFileNameFromAnnotationUsingByteArray() {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

ClientFormUsingByteArray form = new ClientFormUsingByteArray();
form.file = "file content".getBytes(StandardCharsets.UTF_8);
assertThat(client.postMultipartWithPartFilenameUsingByteArray(form)).isEqualTo("clientFile:file content");
form.file = FILE_CONTENT.getBytes(StandardCharsets.UTF_8);
// Using a Multipart bean
assertThat(client.postMultipartWithPartFilenameUsingByteArray(form)).isEqualTo(EXPECTED_OUTPUT);
// Using a field form param
assertThat(client.postMultipartWithPartFilenameUsingByteArray(form.file)).isEqualTo(EXPECTED_OUTPUT);
}

@Test
void shouldUseFileNameFromAnnotationUsingInputStream() {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

var bytes = FILE_CONTENT.getBytes(StandardCharsets.UTF_8);
ClientFormUsingInputStream form = new ClientFormUsingInputStream();
form.file = new ByteArrayInputStream("file content".getBytes(StandardCharsets.UTF_8));
assertThat(client.postMultipartWithPartFilenameUsingInputStream(form)).isEqualTo("clientFile:file content");
form.file = new ByteArrayInputStream(bytes);
// Using a Multipart bean
assertThat(client.postMultipartWithPartFilenameUsingInputStream(form)).isEqualTo(EXPECTED_OUTPUT);
// Using a field form param
assertThat(client.postMultipartWithPartFilenameUsingInputStream(new ByteArrayInputStream(bytes)))
.isEqualTo(EXPECTED_OUTPUT);
}

@Test
void shouldUseFileNameFromAnnotationUsingMultiByte() {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

var list = new ArrayList<Byte>();
var array = "file content".getBytes(StandardCharsets.UTF_8);
var array = FILE_CONTENT.getBytes(StandardCharsets.UTF_8);
for (var b : array) {
list.add(b);
}

ClientFormUsingMultiByte form = new ClientFormUsingMultiByte();
form.file = Multi.createFrom().items(list.stream());
assertThat(client.postMultipartWithPartFilenameUsingMultiByte(form)).isEqualTo("clientFile:file content");
// Using a Multipart bean
assertThat(client.postMultipartWithPartFilenameUsingMultiByte(form)).isEqualTo(EXPECTED_OUTPUT);
// Using a field form param
assertThat(client.postMultipartWithPartFilenameUsingMultiByte(Multi.createFrom().items(list.stream())))
.isEqualTo(EXPECTED_OUTPUT);
}

@Test
void shouldCopyFileContentToString() throws IOException {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

File file = File.createTempFile("MultipartTest", ".txt");
Files.writeString(file.toPath(), "content!");
Files.writeString(file.toPath(), FILE_CONTENT);
file.deleteOnExit();

ClientForm form = new ClientForm();
form.file = file;
assertThat(client.postMultipartWithFileContent(form)).isEqualTo("content!");
assertThat(client.postMultipartWithFileContent(form)).isEqualTo(FILE_CONTENT);
}

@Test
void shouldCopyFileContentToBytes() throws IOException {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

File file = File.createTempFile("MultipartTest", ".txt");
Files.writeString(file.toPath(), "content!");
Files.writeString(file.toPath(), FILE_CONTENT);
file.deleteOnExit();

ClientForm form = new ClientForm();
form.file = file;
assertThat(client.postMultipartWithFileContentAsBytes(form)).isEqualTo("content!");
assertThat(client.postMultipartWithFileContentAsBytes(form)).isEqualTo(FILE_CONTENT);
}

@Test
void shouldCopyFileContentToInputStream() throws IOException {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

File file = File.createTempFile("MultipartTest", ".txt");
Files.writeString(file.toPath(), "content!");
Files.writeString(file.toPath(), FILE_CONTENT);
file.deleteOnExit();

ClientForm form = new ClientForm();
form.file = file;
assertThat(client.postMultipartWithFileContentAsInputStream(form)).isEqualTo("content!");
assertThat(client.postMultipartWithFileContentAsInputStream(form)).isEqualTo(FILE_CONTENT);
}

@Path("/multipart")
Expand Down Expand Up @@ -194,19 +218,19 @@ public static class FormData {

public static class FormDataWithFileContent {
@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
public String fileContent;
}

public static class FormDataWithBytes {
@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
public byte[] fileContentAsBytes;
}

public static class FormDataWithInputStream {
@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
public InputStream fileContentAsInputStream;
}

Expand All @@ -220,26 +244,55 @@ public interface Client {
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilename(@MultipartForm ClientFormUsingFile clientForm);

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilename(
@FormParam("myFile") @PartType(APPLICATION_OCTET_STREAM) @PartFilename(FILE_NAME) File file);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingString(@MultipartForm ClientFormUsingString clientForm);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingString(
@RestForm @PartType(APPLICATION_OCTET_STREAM) @PartFilename(FILE_NAME) String myFile);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingByteArray(@MultipartForm ClientFormUsingByteArray clientForm);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingByteArray(
@FormParam("myFile") @PartType(APPLICATION_OCTET_STREAM) @PartFilename(FILE_NAME) byte[] file);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingInputStream(@MultipartForm ClientFormUsingInputStream clientForm);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingInputStream(
@FormParam("myFile") @PartType(APPLICATION_OCTET_STREAM) @PartFilename(FILE_NAME) InputStream file);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingMultiByte(@MultipartForm ClientFormUsingMultiByte clientForm);

@POST
@Path("/using-form-data")
@Consumes(MediaType.MULTIPART_FORM_DATA)
String postMultipartWithPartFilenameUsingMultiByte(
@FormParam("myFile") @PartType(APPLICATION_OCTET_STREAM) @PartFilename(FILE_NAME) Multi<Byte> file);

@POST
@Path("/file-content")
@Consumes(MediaType.MULTIPART_FORM_DATA)
Expand All @@ -258,15 +311,13 @@ public interface Client {

public static class ClientForm {
@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
public File file;
}

public static class ClientFormUsingFile {
public static final String FILE_NAME = "clientFile";

@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
@PartFilename(FILE_NAME)
public File file;
}
Expand All @@ -275,34 +326,28 @@ public static class ClientFormUsingString {
public static final String FILE_NAME = "clientFile";

@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
@PartFilename(FILE_NAME)
public String file;
}

public static class ClientFormUsingByteArray {
public static final String FILE_NAME = "clientFile";

@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
@PartFilename(FILE_NAME)
public byte[] file;
}

public static class ClientFormUsingInputStream {
public static final String FILE_NAME = "clientFile";

@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
@PartFilename(FILE_NAME)
public InputStream file;
}

public static class ClientFormUsingMultiByte {
public static final String FILE_NAME = "clientFile";

@FormParam("myFile")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartType(APPLICATION_OCTET_STREAM)
@PartFilename(FILE_NAME)
public Multi<Byte> file;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Used on fields of {@link MultipartForm} POJOs to designate the filename of a part.
* This is only applicable in the client, not the server.
*/
@Target({ ElementType.FIELD })
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface PartFilename {
String value();
Expand Down