liubao68 closed pull request #661: [SCB-494] Delete temp file after download
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/661
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DownloadSchema.java
 
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DownloadSchema.java
index 0fbd6ee69..712551189 100644
--- 
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DownloadSchema.java
+++ 
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DownloadSchema.java
@@ -21,12 +21,16 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.UUID;
 
+import javax.servlet.http.Part;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.foundation.common.part.FilePart;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
 import org.springframework.core.io.ByteArrayResource;
 import org.springframework.core.io.Resource;
 import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -35,8 +39,44 @@
 import io.swagger.annotations.ApiResponses;
 
 @RestSchema(schemaId = "download")
-@RequestMapping(path = "/download", produces = 
MediaType.APPLICATION_OCTET_STREAM_VALUE)
+@RequestMapping(path = "/download")
 public class DownloadSchema {
+  File tempDir = new File("downloadTemp");
+
+  public DownloadSchema() throws IOException {
+    FileUtils.forceMkdir(tempDir);
+  }
+
+  // content is file name
+  protected File createTempFile() throws IOException {
+    String name = "download-" + UUID.randomUUID().toString() + ".txt";
+    File file = new File(tempDir, name);
+    FileUtils.write(file, name);
+    return file;
+  }
+
+  // customize HttpHeaders.CONTENT_DISPOSITION to be 
"attachment;filename=tempFileEntity.txt"
+  @GetMapping(path = "/tempFileEntity")
+  public ResponseEntity<Part> downloadTempFileEntity() throws IOException {
+    File file = createTempFile();
+
+    return ResponseEntity
+        .ok()
+        .header(HttpHeaders.CONTENT_DISPOSITION, 
"attachment;filename=tempFileEntity.txt")
+        .body(new FilePart(null, file)
+            .setDeleteAfterFinished(true));
+  }
+
+  // generate HttpHeaders.CONTENT_DISPOSITION to be 
"attachment;filename=tempFilePart.txt" automatically
+  @GetMapping(path = "/tempFilePart")
+  public Part downloadTempFilePart() throws IOException {
+    File file = createTempFile();
+
+    return new FilePart(null, file)
+        .setDeleteAfterFinished(true)
+        .setSubmittedFileName("tempFilePart.txt");
+  }
+
   @GetMapping(path = "/file")
   public File downloadFile() throws IOException {
     return new 
File(this.getClass().getClassLoader().getResource("microservice.yaml").getFile());
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/AbstractPart.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/AbstractPart.java
index 4027f8f88..653d0f909 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/AbstractPart.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/AbstractPart.java
@@ -60,9 +60,10 @@ public String getSubmittedFileName() {
     return submittedFileName;
   }
 
-  public void setSubmittedFileName(String submittedFileName) {
+  public AbstractPart setSubmittedFileName(String submittedFileName) {
     this.submittedFileName = submittedFileName;
     updateContentType();
+    return this;
   }
 
   private void updateContentType() {
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePart.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePart.java
index 2b2a4da62..ef2904797 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePart.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePart.java
@@ -24,9 +24,11 @@
 
 import org.apache.commons.io.FileUtils;
 
-public class FilePart extends AbstractPart {
+public class FilePart extends AbstractPart implements FilePartForSend {
   private File file;
 
+  private boolean deleteAfterFinished;
+
   public FilePart(String name, String file) {
     this(name, new File(file));
   }
@@ -51,4 +53,24 @@ public long getSize() {
   public void write(String fileName) throws IOException {
     FileUtils.copyFile(file, new File(fileName));
   }
+
+  @Override
+  public void delete() throws IOException {
+    file.delete();
+  }
+
+  @Override
+  public boolean isDeleteAfterFinished() {
+    return deleteAfterFinished;
+  }
+
+  public FilePart setDeleteAfterFinished(boolean deleteAfterFinished) {
+    this.deleteAfterFinished = deleteAfterFinished;
+    return this;
+  }
+
+  @Override
+  public String getAbsolutePath() {
+    return file.getAbsolutePath();
+  }
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePartForSend.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePartForSend.java
new file mode 100644
index 000000000..f86e696a6
--- /dev/null
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePartForSend.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.common.part;
+
+import javax.servlet.http.Part;
+
+public interface FilePartForSend extends Part {
+  boolean isDeleteAfterFinished();
+
+  String getAbsolutePath();
+}
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestFilePart.java
 
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestFilePart.java
index 45f912d94..d06eda891 100644
--- 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestFilePart.java
+++ 
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestFilePart.java
@@ -71,6 +71,21 @@ public void write() throws IOException {
 
     part.write(destFile.getPath());
     Assert.assertEquals(content, FileUtils.readFileToString(destFile));
-    destFile.delete();
+
+    FilePart destPart = new FilePart(null, destFile);
+    destPart.delete();
+    Assert.assertFalse(destFile.exists());
+  }
+
+  @Test
+  public void deleteAfterFinished() {
+    Assert.assertFalse(part.isDeleteAfterFinished());
+
+    
Assert.assertTrue(part.setDeleteAfterFinished(true).isDeleteAfterFinished());
+  }
+
+  @Test
+  public void getAbsolutePath() {
+    Assert.assertEquals(file.getAbsolutePath(), part.getAbsolutePath());
   }
 }
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
index 9f5db5549..d467058f9 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
@@ -29,7 +29,10 @@
 
 import org.apache.commons.io.IOUtils;
 import org.apache.servicecomb.foundation.common.http.HttpStatus;
+import org.apache.servicecomb.foundation.common.part.FilePartForSend;
 import org.apache.servicecomb.foundation.vertx.stream.InputStreamToReadStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import io.vertx.core.Context;
 import io.vertx.core.Vertx;
@@ -37,6 +40,8 @@
 import io.vertx.core.streams.Pump;
 
 public class VertxServerResponseToHttpServletResponse extends 
AbstractHttpServletResponse {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(VertxServerResponseToHttpServletResponse.class);
+
   private Context context;
 
   private HttpServerResponse serverResponse;
@@ -169,5 +174,12 @@ protected void prepareSendPartHeader(Part part) {
 
   protected void clearPartResource(Part part, InputStream is) {
     IOUtils.closeQuietly(is);
+    if (FilePartForSend.class.isInstance(part) && ((FilePartForSend) 
part).isDeleteAfterFinished()) {
+      try {
+        part.delete();
+      } catch (IOException e) {
+        LOGGER.error("Failed to delete temp file: {}.", ((FilePartForSend) 
part).getAbsolutePath(), e);
+      }
+    }
   }
 }
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
index c69d41cc2..fd6202cee 100644
--- 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
@@ -17,8 +17,10 @@
 
 package org.apache.servicecomb.foundation.vertx.http;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
@@ -26,7 +28,9 @@
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response.StatusType;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.servicecomb.foundation.common.http.HttpStatus;
+import org.apache.servicecomb.foundation.common.part.FilePart;
 import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.Before;
@@ -378,4 +382,28 @@ public void sendPart_succ(@Mocked Part part, @Mocked 
InputStream inputStream)
 
     Assert.assertNull(future.get());
   }
+
+  @Test
+  public void clearPartResource_deleteFile() throws IOException {
+    File file = new File("target", UUID.randomUUID().toString() + ".txt");
+    FileUtils.write(file, "content");
+    FilePart part = new FilePart(null, file).setDeleteAfterFinished(true);
+
+    Assert.assertTrue(file.exists());
+    response.clearPartResource(part, part.getInputStream());
+    Assert.assertFalse(file.exists());
+  }
+
+  @Test
+  public void clearPartResource_notDeleteFile() throws IOException {
+    File file = new File("target", UUID.randomUUID().toString() + ".txt");
+    FileUtils.write(file, "content");
+    FilePart part = new FilePart(null, file);
+
+    Assert.assertTrue(file.exists());
+    response.clearPartResource(part, part.getInputStream());
+    Assert.assertTrue(file.exists());
+
+    file.delete();
+  }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to