This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit afb77b3110bb7508c27f40408ecab59b12be0d63 Author: wujimin <[email protected]> AuthorDate: Sun Apr 22 17:59:56 2018 +0800 [SCB-487] add download consumer demo --- .../java/org/apache/servicecomb/demo/TestMgr.java | 10 +- .../client/CodeFirstRestTemplateSpringmvc.java | 4 + .../demo/springmvc/client/DownloadSchemaIntf.java | 37 ++++++ .../demo/springmvc/client/TestDownload.java | 124 +++++++++++++++++++++ .../demo/springmvc/server/DownloadSchema.java | 91 ++++++++++++--- 5 files changed, 247 insertions(+), 19 deletions(-) diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java index c72bb36..b0086f6 100644 --- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java +++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java @@ -40,6 +40,10 @@ public class TestMgr { } public static void check(Object expect, Object real) { + check(expect, real, null); + } + + public static void check(Object expect, Object real, Throwable error) { if (expect == real) { return; } @@ -48,7 +52,11 @@ public class TestMgr { String strReal = String.valueOf(real); if (!strExpect.equals(strReal)) { - errorList.add(new Error(msg + " | Expect " + strExpect + ", but " + strReal)); + Error newError = new Error(msg + " | Expect " + strExpect + ", but " + strReal); + if (error != null) { + newError.setStackTrace(error.getStackTrace()); + } + errorList.add(newError); } } diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java index f23e882..2303cc0 100644 --- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java @@ -70,8 +70,12 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate { private TestGeneric testGeneric = new TestGeneric(); + private TestDownload testDownload = new TestDownload(); + @Override protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) { + testDownload.runRest(); + try { testUpload(template, cseUrlPrefix); } catch (IOException e) { diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/DownloadSchemaIntf.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/DownloadSchemaIntf.java new file mode 100644 index 0000000..48b9a0f --- /dev/null +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/DownloadSchemaIntf.java @@ -0,0 +1,37 @@ +/* + * 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.demo.springmvc.client; + +import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart; + +public interface DownloadSchemaIntf { + ReadStreamPart tempFileEntity(String content); + + ReadStreamPart tempFilePart(String content); + + ReadStreamPart file(String content); + + ReadStreamPart chineseAndSpaceFile(String content); + + ReadStreamPart resource(String content); + + ReadStreamPart entityResource(String content); + + ReadStreamPart entityInputStream(String content); + + ReadStreamPart netInputStream(String content); +} diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java new file mode 100644 index 0000000..303c001 --- /dev/null +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java @@ -0,0 +1,124 @@ +/* + * 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.demo.springmvc.client; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.apache.commons.io.FileUtils; +import org.apache.servicecomb.demo.TestMgr; +import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart; +import org.apache.servicecomb.provider.pojo.Invoker; +import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate; +import org.springframework.web.client.RestTemplate; + +public class TestDownload { + private File dir = new File("target/download"); + + private DownloadSchemaIntf intf = Invoker.createProxy("springmvc", "download", DownloadSchemaIntf.class); + + private RestTemplate restTemplate = new CseRestTemplate(); + + private String prefix = "cse://springmvc/download"; + + private List<CompletableFuture<?>> futures = new ArrayList<>(); + + private String content = "file content"; + + public TestDownload() { + FileUtils.deleteQuietly(dir); + } + + private String readFileToString(File file) { + try { + return FileUtils.readFileToString(file); + } catch (IOException e) { + return "read file failed:" + e.getMessage(); + } + } + + private CompletableFuture<File> checkFile(ReadStreamPart part) { + CompletableFuture<File> future = part.saveToFile("target/download/" + + UUID.randomUUID().toString() + + "-" + + part.getSubmittedFileName()); + return checkFuture(future); + } + + private <T> CompletableFuture<T> checkFuture(CompletableFuture<T> future) { + Error error = new Error(); + future.whenComplete((result, e) -> { + Object value = result; + if (File.class.isInstance(value)) { + value = readFileToString((File) value); + ((File) value).delete(); + } else if (byte[].class.isInstance(value)) { + value = new String((byte[]) value); + } + + TestMgr.check(content, value, error); + }); + + return future; + } + + private ReadStreamPart templateGet(String methodPath) { + return restTemplate + .getForObject(prefix + "/" + methodPath + "?content={content}", + ReadStreamPart.class, + content); + } + + public void runRest() { + futures.add(checkFile(intf.tempFileEntity(content))); + futures.add(checkFuture(templateGet("tempFileEntity").saveAsBytes())); + + futures.add(checkFile(intf.tempFilePart(content))); + futures.add(checkFuture(templateGet("tempFilePart").saveAsString())); + + futures.add(checkFile(intf.file(content))); + futures.add(checkFuture(templateGet("file").saveAsString())); + + // fix in next PR + // futures.add(checkFile(intf.chineseAndSpaceFile(content))); + // futures.add(checkFuture(templateGet("chineseAndSpaceFile").saveAsString())); + + futures.add(checkFile(intf.resource(content))); + futures.add(checkFuture(templateGet("resource").saveAsString())); + + futures.add(checkFile(intf.entityResource(content))); + futures.add(checkFuture(templateGet("entityResource").saveAsString())); + + futures.add(checkFile(intf.entityInputStream(content))); + futures.add(checkFuture(templateGet("entityInputStream").saveAsString())); + + futures.add(checkFile(intf.netInputStream(content))); + futures.add(checkFuture(templateGet("netInputStream").saveAsString())); + + try { + CompletableFuture + .allOf(futures.toArray(new CompletableFuture[futures.size()])) + .get(); + } catch (InterruptedException | ExecutionException e1) { + } + } +} 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 7125511..c6124d2 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 @@ -20,17 +20,26 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.UUID; import javax.servlet.http.Part; import org.apache.commons.io.FileUtils; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.bootstrap.HttpServer; +import org.apache.http.impl.bootstrap.ServerBootstrap; 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; @@ -41,24 +50,45 @@ import io.swagger.annotations.ApiResponses; @RestSchema(schemaId = "download") @RequestMapping(path = "/download") public class DownloadSchema { - File tempDir = new File("downloadTemp"); + File tempDir = new File("target/downloadTemp"); public DownloadSchema() throws IOException { + FileUtils.deleteQuietly(tempDir); FileUtils.forceMkdir(tempDir); + + // for download from net stream case + HttpServer server = ServerBootstrap + .bootstrap() + .setListenerPort(9000) + .registerHandler("/download/netInputStream", (req, resp, context) -> { + String uri = req.getRequestLine().getUri(); + String query = URI.create(uri).getQuery(); + int idx = query.indexOf('='); + String content = query.substring(idx + 1); + content = URLDecoder.decode(content, StandardCharsets.UTF_8.name()); + resp.setEntity(new StringEntity(content, StandardCharsets.UTF_8.name())); + }) + .create(); + server.start(); + } + + protected File createTempFile(String content) throws IOException { + return createTempFile(null, content); } - // content is file name - protected File createTempFile() throws IOException { - String name = "download-" + UUID.randomUUID().toString() + ".txt"; + protected File createTempFile(String name, String content) throws IOException { + if (name == null) { + name = "download-" + UUID.randomUUID().toString() + ".txt"; + } File file = new File(tempDir, name); - FileUtils.write(file, name); + FileUtils.write(file, content); return file; } // customize HttpHeaders.CONTENT_DISPOSITION to be "attachment;filename=tempFileEntity.txt" @GetMapping(path = "/tempFileEntity") - public ResponseEntity<Part> downloadTempFileEntity() throws IOException { - File file = createTempFile(); + public ResponseEntity<Part> tempFileEntity(String content) throws IOException { + File file = createTempFile(content); return ResponseEntity .ok() @@ -69,8 +99,8 @@ public class DownloadSchema { // generate HttpHeaders.CONTENT_DISPOSITION to be "attachment;filename=tempFilePart.txt" automatically @GetMapping(path = "/tempFilePart") - public Part downloadTempFilePart() throws IOException { - File file = createTempFile(); + public Part tempFilePart(String content) throws IOException { + File file = createTempFile(content); return new FilePart(null, file) .setDeleteAfterFinished(true) @@ -78,19 +108,27 @@ public class DownloadSchema { } @GetMapping(path = "/file") - public File downloadFile() throws IOException { - return new File(this.getClass().getClassLoader().getResource("microservice.yaml").getFile()); + public File file(String content) throws IOException { + return createTempFile("file.txt", content); + } + + @GetMapping(path = "/chineseAndSpaceFile") + public Part chineseAndSpaceFile(String content) throws IOException { + File file = createTempFile(content); + return new FilePart(null, file) + .setDeleteAfterFinished(true) + .setSubmittedFileName("测 试.test.txt"); } @GetMapping(path = "/resource") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = ""), }) - public Resource downloadResource() throws IOException { - return new ByteArrayResource("abc".getBytes(StandardCharsets.UTF_8)) { + public Resource resource(String content) throws IOException { + return new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8)) { @Override public String getFilename() { - return "abc.txt"; + return "resource.txt"; } }; } @@ -99,21 +137,38 @@ public class DownloadSchema { @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = ""), }) - public ResponseEntity<Resource> downloadEntityResource() throws IOException { + public ResponseEntity<Resource> entityResource(String content) throws IOException { return ResponseEntity .ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=entityResource.txt") - .body(new ByteArrayResource("entityResource".getBytes(StandardCharsets.UTF_8))); + .body(new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8))); } @GetMapping(path = "/entityInputStream") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = ""), }) - public ResponseEntity<InputStream> downloadEntityInputStream() throws IOException { + public ResponseEntity<InputStream> entityInputStream(String content) throws IOException { return ResponseEntity .ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=entityInputStream.txt") - .body(new ByteArrayInputStream("entityInputStream".getBytes(StandardCharsets.UTF_8))); + .body(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))); + } + + @GetMapping(path = "/netInputStream") + @ApiResponses({ + @ApiResponse(code = 200, response = File.class, message = ""), + }) + public ResponseEntity<InputStream> netInputStream(String content) throws IOException { + URL url = new URL("http://localhost:9000/download/netInputStream?content=" + + URLEncoder.encode(content, StandardCharsets.UTF_8.name())); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + return ResponseEntity + .ok() + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=netInputStream.txt") + .body(conn.getInputStream()); } } -- To stop receiving notification emails like this one, please contact [email protected].
