This is an automated email from the ASF dual-hosted git repository.
fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
The following commit(s) were added to refs/heads/main by this push:
new ded1eb26574 CAMEL-21701: Make single file upload easy to access from
message body
ded1eb26574 is described below
commit ded1eb26574a3bbd1f201100feb0d11c023e907c
Author: Croway <[email protected]>
AuthorDate: Tue Feb 4 11:39:01 2025 +0100
CAMEL-21701: Make single file upload easy to access from message body
---
.../src/main/docs/platform-http.json | 9 +--
.../springboot/SpringBootPlatformHttpBinding.java | 8 +++
.../SpringBootPlatformHttpEngineTest.java | 68 ++++++++++++++++++++--
3 files changed, 74 insertions(+), 11 deletions(-)
diff --git
a/components-starter/camel-platform-http-starter/src/main/docs/platform-http.json
b/components-starter/camel-platform-http-starter/src/main/docs/platform-http.json
index ac25fa04700..d058867af90 100644
---
a/components-starter/camel-platform-http-starter/src/main/docs/platform-http.json
+++
b/components-starter/camel-platform-http-starter/src/main/docs/platform-http.json
@@ -17,15 +17,13 @@
"name": "camel.component.platform-http.autowired-enabled",
"type": "java.lang.Boolean",
"description": "Whether autowiring is enabled. This is used for
automatic autowiring options (the option must be marked as autowired) by
looking up in the registry to find if there is a single instance of matching
type, which then gets configured on the component. This can be used for
automatic configuring JDBC data sources, JMS connection factories, AWS Clients,
etc.",
- "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration",
- "defaultValue": true
+ "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration"
},
{
"name": "camel.component.platform-http.bridge-error-handler",
"type": "java.lang.Boolean",
"description": "Allows for bridging the consumer to the Camel routing
Error Handler, which mean any exceptions (if possible) occurred while the Camel
consumer is trying to pickup incoming messages, or the likes, will now be
processed as a message and handled by the routing Error Handler. Important:
This is only possible if the 3rd party component allows Camel to be alerted if
an exception was thrown. Some components handle this internally only, and
therefore bridgeErrorHandler is n [...]
- "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration",
- "defaultValue": false
+ "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration"
},
{
"name": "camel.component.platform-http.customizer.enabled",
@@ -48,8 +46,7 @@
"name": "camel.component.platform-http.handle-write-response-error",
"type": "java.lang.Boolean",
"description": "When Camel is complete processing the message, and the
HTTP server is writing response. This option controls whether Camel should
catch any failure during writing response and store this on the Exchange, which
allows onCompletion\/UnitOfWork to regard the Exchange as failed and have
access to the caused exception from the HTTP server.",
- "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration",
- "defaultValue": false
+ "sourceType":
"org.apache.camel.component.platform.http.springboot.PlatformHttpComponentConfiguration"
},
{
"name": "camel.component.platform-http.header-filter-strategy",
diff --git
a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
index 4e145ea385b..415d5c5f0a6 100644
---
a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
+++
b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpBinding.java
@@ -98,6 +98,8 @@ public class SpringBootPlatformHttpBinding extends
DefaultHttpBinding {
// check if there is multipart files, if so will put it into
DataHandler
if (request instanceof MultipartHttpServletRequest
multipartHttpServletRequest) {
File tmpFolder = (File)
request.getServletContext().getAttribute(ServletContext.TEMPDIR);
+ boolean isSingleAttachment =
multipartHttpServletRequest.getFileMap() != null &&
+ multipartHttpServletRequest.getFileMap().keySet().size()
== 1;
multipartHttpServletRequest.getFileMap().forEach((name,
multipartFile) -> {
try {
Path uploadedTmpFile = Paths.get(tmpFolder.getPath(),
UUID.randomUUID().toString());
@@ -122,6 +124,12 @@ public class SpringBootPlatformHttpBinding extends
DefaultHttpBinding {
if (accepted) {
AttachmentMessage am =
message.getExchange().getMessage(AttachmentMessage.class);
am.addAttachment(name, new DataHandler(new
CamelFileDataSource(uploadedTmpFile.toFile(), name)));
+
+ // populate body in case there is only one attachment
+ if (isSingleAttachment) {
+ message.setHeader(Exchange.FILE_NAME, name);
+ message.setBody(uploadedTmpFile);
+ }
} else {
LOG.debug(
"Cannot add file as attachment: {} because the
file is not accepted according to fileNameExtWhitelist: {}",
diff --git
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
index 012df2f34c8..c9f9d0959b1 100644
---
a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
+++
b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngineTest.java
@@ -24,6 +24,7 @@ import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spring.boot.CamelAutoConfiguration;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -37,12 +38,17 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.File;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import static io.restassured.RestAssured.get;
import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -68,6 +74,8 @@ public class SpringBootPlatformHttpEngineTest {
RestAssured.port = port;
}
+ private static final List<String> attachmentIds = new ArrayList<>();
+
@Configuration
public static class TestConfiguration {
@@ -77,15 +85,30 @@ public class SpringBootPlatformHttpEngineTest {
@Override
public void configure() {
rest()
- .post("upload").to("direct:upload");
+ .post("uploadSingle").to("direct:uploadSingle")
+ .post("uploadMulti").to("direct:uploadMulti");
- from("direct:upload")
+ from("direct:uploadSingle")
.process(exchange -> {
AttachmentMessage message =
exchange.getMessage(AttachmentMessage.class);
DataHandler attachment =
message.getAttachment(attachmentId);
- message.setBody(attachment.getContent());
+ exchange.getMessage().setHeader("myDataHandler",
attachment);
+
exchange.getMessage().setBody(attachment.getContent());
});
+ from("direct:uploadMulti")
+ .process(exchange -> {
+ AttachmentMessage message =
exchange.getMessage(AttachmentMessage.class);
+
+ String result = "";
+ for (String attachmentId : attachmentIds) {
+ DataHandler attachment =
message.getAttachment(attachmentId);
+ result +=
IOUtils.toString(attachment.getInputStream(), Charset.defaultCharset());
+ }
+
+
exchange.getIn().setHeader("ConcatFileContent", result);
+ });
+
from("platform-http:/form/post")
.convertBodyTo(String.class);
@@ -117,7 +140,7 @@ public class SpringBootPlatformHttpEngineTest {
}
@Test
- public void testAttachment() throws Exception {
+ public void testSingleAttachment() throws Exception {
final String attachmentId = "myTestFile";
final String fileContent = "Test multipart upload content";
final File tempFile = File.createTempFile("platform-http", ".txt");
@@ -127,12 +150,47 @@ public class SpringBootPlatformHttpEngineTest {
given()
.multiPart(attachmentId, tempFile)
.when()
- .post("/upload")
+ .post("/uploadSingle")
.then()
.statusCode(200)
+ // Assert that the attachment is a DataHandler
+ .header("myDataHandler",
containsString("jakarta.activation.DataHandler"))
.body(is(fileContent));
}
+ @Test
+ public void testMultiAttachments() throws Exception {
+ attachmentIds.add("myFirstTestFile");
+ attachmentIds.add("mySecondTestFile");
+
+ String tmpDirectory = null;
+ List<File> tempFiles = new ArrayList<>(attachmentIds.size());
+ for (String attachmentId : attachmentIds) {
+ final String fileContent = "Test multipart upload content " +
attachmentId;
+ File tempFile;
+ if (tmpDirectory == null) {
+ tempFile = File.createTempFile("platform-http-" +
attachmentId, ".txt");
+ } else {
+ tempFile = File.createTempFile("platform-http-" +
attachmentId, ".txt", new File(tmpDirectory));
+ }
+
+ tempFiles.add(tempFile);
+ tmpDirectory = tempFile.getParent();
+ Files.write(tempFile.toPath(),
fileContent.getBytes(StandardCharsets.UTF_8));
+ }
+
+ given()
+ .multiPart(attachmentIds.get(0), tempFiles.get(0))
+ .multiPart(attachmentIds.get(1), tempFiles.get(1))
+ .when()
+ .post("/uploadMulti")
+ .then()
+ .statusCode(204)
+ .body(emptyOrNullString())
+ .header("ConcatFileContent",
+ is("Test multipart upload content myFirstTestFileTest
multipart upload content mySecondTestFile"));
+ }
+
@Test
public void formPost() {
given()