diff --git a/src/main/java/io/sinistral/proteus/server/Extractors.java b/src/main/java/io/sinistral/proteus/server/Extractors.java index 2e7334c..dc97909 100644 --- a/src/main/java/io/sinistral/proteus/server/Extractors.java +++ b/src/main/java/io/sinistral/proteus/server/Extractors.java @@ -205,6 +205,32 @@ public static java.util.Optional filePath(final HttpServerExchange exchan { return java.util.Optional.ofNullable(exchange.getAttachment(FormDataParser.FORM_DATA).get(name)).map(Deque::getFirst).map(FormValue::getPath); } + + public static java.util.Optional byteBuffer(final HttpServerExchange exchange, final String name) + { + return Optional.filePath(exchange,name).map( fp -> { + + + try(final FileChannel fileChannel = FileChannel.open(fp, StandardOpenOption.READ)) + { + final ByteBuffer buffer = ByteBuffer.allocate((int)fileChannel.size()); + + fileChannel.read(buffer); + + buffer.flip(); + + return buffer; + + } catch(Exception e) + { + return null; + } + + }); + + + + } } public static class Header @@ -331,7 +357,7 @@ public static Path filePath(final HttpServerExchange exchange, final String nam } } - public static ByteBuffer fileBytes(final HttpServerExchange exchange, final String name) throws IOException + public static ByteBuffer byteBuffer(final HttpServerExchange exchange, final String name) throws IOException { final Path filePath = filePath(exchange,name); diff --git a/src/main/java/io/sinistral/proteus/server/ServerResponse.java b/src/main/java/io/sinistral/proteus/server/ServerResponse.java index fd1a95e..9f6c218 100644 --- a/src/main/java/io/sinistral/proteus/server/ServerResponse.java +++ b/src/main/java/io/sinistral/proteus/server/ServerResponse.java @@ -211,13 +211,19 @@ public ServerResponse applicationJson() { this.processJson = true; } - this.contentType = MimeTypes.APPLICATION_JSON_TYPE; + this.contentType = javax.ws.rs.core.MediaType.APPLICATION_JSON; return this; } public ServerResponse textHtml() { - this.contentType = MimeTypes.TEXT_HTML_TYPE; + this.contentType = javax.ws.rs.core.MediaType.TEXT_HTML; + return this; + } + + public ServerResponse applicationOctetStream() + { + this.contentType = javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; return this; } @@ -227,13 +233,13 @@ public ServerResponse applicationXml() { this.processXml = true; } - this.contentType = MimeTypes.APPLICATION_XML_TYPE; + this.contentType = javax.ws.rs.core.MediaType.APPLICATION_XML; return this; } public ServerResponse textPlain() { - this.contentType = MimeTypes.TEXT_PLAIN_TYPE; + this.contentType = javax.ws.rs.core.MediaType.TEXT_PLAIN; return this; } diff --git a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java index 288e9ad..13cd0dd 100644 --- a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java +++ b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java @@ -91,10 +91,10 @@ public enum TypeHandler FilePathType("$T $L = $T.filePath(exchange,$S)", true, java.nio.file.Path.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING), AnyType("$T $L = $T.any(exchange)", true, com.jsoniter.any.Any.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class), JsonIteratorType("$T $L = $T.jsonIterator(exchange)", true, com.jsoniter.JsonIterator.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class), - ModelType("$T $L = io.sinistral.proteus.server.Extractors.model(exchange,$L)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL, StatementParameterType.LITERAL), + ModelType("$T $L = $T.model(exchange,$L)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.LITERAL), //EnumType("$T $L = $T.enumValue(exchange,$T.class,$S)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.TYPE, StatementParameterType.STRING), - ByteBufferType("$T $L = $T.fileBytes(exchange,$S)", false, java.nio.ByteBuffer.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING), + ByteBufferType("$T $L = $T.byteBuffer(exchange,$S)", true, java.nio.ByteBuffer.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING), DateType("$T $L = $T.date(exchange,$S)", false, java.util.Date.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING), ZonedDateTimeType("$T $L = $T.zonedDateTime(exchange,$S)",false,java.time.ZonedDateTime.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING ), OffsetDateTimeType("$T $L = $T.offsetDateTime(exchange,$S)",false,java.time.OffsetDateTime.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.class, StatementParameterType.STRING ), @@ -128,6 +128,9 @@ public enum TypeHandler OptionalIntegerType("$T $L = $T.integerValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), OptionalBooleanType("$T $L = $T.booleanValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), OptionalFilePathType("$T<$T> $L = $T.filePath(exchange,$S)", true, Optional.class, java.nio.file.Path.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), + + OptionalByteBufferType("$T<$T> $L = $T.byteBuffer(exchange,$S)", true, Optional.class, java.nio.ByteBuffer.class, StatementParameterType.LITERAL,io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), + OptionalFloatType("$T $L = $T.floatValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), OptionalDoubleType("$T $L = $T.doubleValue(exchange,$S)", false, Optional.class, StatementParameterType.LITERAL, io.sinistral.proteus.server.Extractors.Optional.class, StatementParameterType.STRING), @@ -433,6 +436,10 @@ else if (type.getTypeName().contains("java.nio.file.Path")) { return OptionalFilePathType; } + else if (type.getTypeName().contains("java.nio.ByteBuffer")) + { + return OptionalByteBufferType; + } else { try diff --git a/src/test/java/io/sinistral/proteus/controllers/Tests.java b/src/test/java/io/sinistral/proteus/controllers/Tests.java index 8820ecc..fa38d8a 100644 --- a/src/test/java/io/sinistral/proteus/controllers/Tests.java +++ b/src/test/java/io/sinistral/proteus/controllers/Tests.java @@ -5,6 +5,7 @@ import static io.sinistral.proteus.server.ServerResponse.response; +import java.io.IOException; import java.nio.ByteBuffer; import java.time.Instant; import java.time.OffsetDateTime; @@ -18,8 +19,10 @@ import java.util.concurrent.CompletableFuture; import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -27,6 +30,7 @@ import javax.ws.rs.core.MediaType; import com.google.common.collect.ImmutableMap; +import com.google.common.io.Files; import com.google.inject.Singleton; import com.jsoniter.output.JsonStream; @@ -135,6 +139,32 @@ public CompletableFuture>> responseFu return CompletableFuture.completedFuture(response( ImmutableMap.of("message", "success") ).applicationJson()); } + @POST + @Path("/response/file/path") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes("*/*") + @ApiOperation(value = "Upload file path endpoint", httpMethod = "POST" ) + public ServerResponse responseUploadFilePath(ServerRequest request, @FormParam("file") java.nio.file.Path file ) throws Exception + { + + return response(ByteBuffer.wrap(Files.toByteArray(file.toFile()))).applicationOctetStream(); + + + } + + @POST + @Path("/response/file/bytebuffer") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes("*/*") + @ApiOperation(value = "Upload file path endpoint", httpMethod = "POST" ) + public ServerResponse responseUploadByteBuffer(ServerRequest request, @FormParam("file") ByteBuffer file ) throws Exception + { + + return response(file).applicationOctetStream(); + + + } + @GET @Path("/response/future/user") @ApiOperation(value = "Future user endpoint", httpMethod = "GET" ) diff --git a/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java b/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java index fbe4d99..244bc0f 100644 --- a/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java +++ b/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java @@ -7,6 +7,9 @@ import static org.junit.Assert.assertThat; import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URI; @@ -27,6 +30,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; +import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Test; @@ -59,6 +63,7 @@ public class TestControllerEndpoints private static String USER_JSON_RESPONSE = "{\r\n \"id\": 123,\r\n \"type\": \"GUEST\"\r\n}"; private static String USER_XML_RESPONSE = "\r\n\r\n\t123\r\n\tGUEST\r\n"; + private File file = null; @Before public void setUp(){ @@ -67,6 +72,9 @@ public void setUp(){ RestAssured.baseURI = "http://localhost:8090/v1"; RestAssured.enableLoggingOfRequestAndResponseIfValidationFails(); + + file = new File(getClass().getClassLoader().getResource("data/video.mp4").toURI()); + } catch (Exception e) { // TODO Auto-generated catch block @@ -133,6 +141,58 @@ public void responseMap() given().log().all().accept(ContentType.JSON).when().get("tests/response/future/map").then().log().all().statusCode(200).and().body("message",is("success")); } + @Test + public void responseUploadFilePathParameter() + { + + try + { + + + final InputStream is = given().multiPart("file", file).log().uri().accept(ContentType.ANY).when().post("tests/response/file/path").asInputStream(); + + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + IOUtils.copy(is, byteArrayOutputStream); + IOUtils.closeQuietly(byteArrayOutputStream); + IOUtils.closeQuietly(is); + + + assertThat(byteArrayOutputStream.size(), equalTo( Long.valueOf(file.length()).intValue() )); + + + } catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + @Test + public void responseUploadByteBufferParameter() + { + + try + { + + final InputStream is = given().multiPart("file", file).log().uri().accept(ContentType.ANY).when().post("tests/response/file/bytebuffer").asInputStream(); + + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + IOUtils.copy(is, byteArrayOutputStream); + IOUtils.closeQuietly(byteArrayOutputStream); + IOUtils.closeQuietly(is); + + + assertThat(byteArrayOutputStream.size(), equalTo( Long.valueOf(file.length()).intValue() )); + + } catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + @Test public void responseComplexParameters() { diff --git a/src/test/resources/data/video.mp4 b/src/test/resources/data/video.mp4 new file mode 100644 index 0000000..ed139d6 Binary files /dev/null and b/src/test/resources/data/video.mp4 differ