-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support AsyncFile, Path. Added PathPart and FilePart
- Loading branch information
Showing
27 changed files
with
857 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
...ain/java/io/quarkus/resteasy/reactive/common/runtime/VertxAsyncFileMessageBodyWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package io.quarkus.resteasy.reactive.common.runtime; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Type; | ||
|
||
import javax.ws.rs.WebApplicationException; | ||
import javax.ws.rs.core.MediaType; | ||
import javax.ws.rs.core.MultivaluedMap; | ||
import javax.ws.rs.ext.MessageBodyWriter; | ||
|
||
import io.vertx.core.file.AsyncFile; | ||
|
||
public class VertxAsyncFileMessageBodyWriter implements MessageBodyWriter<AsyncFile> { | ||
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { | ||
// allow for subtypes, such as AsyncFileImpl | ||
return AsyncFile.class.isAssignableFrom(type); | ||
} | ||
|
||
public void writeTo(AsyncFile asyncFile, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, | ||
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { | ||
throw new UnsupportedOperationException("Returning an AsyncFile is not supported with WriterInterceptors"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
...oyment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package io.quarkus.resteasy.reactive.server.test.providers; | ||
|
||
import java.io.File; | ||
import java.nio.file.Paths; | ||
|
||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
|
||
import org.jboss.resteasy.reactive.FilePart; | ||
import org.jboss.resteasy.reactive.PathPart; | ||
|
||
import io.smallrye.mutiny.Uni; | ||
import io.vertx.core.file.AsyncFile; | ||
import io.vertx.core.file.OpenOptions; | ||
import io.vertx.ext.web.RoutingContext; | ||
|
||
@Path("providers/file") | ||
public class FileResource { | ||
|
||
private static final String FILE = "src/test/resources/lorem.txt"; | ||
|
||
@Path("file") | ||
@GET | ||
public File getFile() { | ||
return new File(FILE); | ||
} | ||
|
||
@Path("file-partial") | ||
@GET | ||
public FilePart getFilePart() { | ||
return new FilePart(new File(FILE), 20, 10); | ||
} | ||
|
||
@Path("path") | ||
@GET | ||
public java.nio.file.Path getPath() { | ||
return Paths.get(FILE); | ||
} | ||
|
||
@Path("path-partial") | ||
@GET | ||
public PathPart getPathPart() { | ||
return new PathPart(Paths.get(FILE), 20, 10); | ||
} | ||
|
||
@Path("async-file") | ||
@GET | ||
public Uni<AsyncFile> getAsyncFile(RoutingContext vertxRequest) { | ||
return Uni.createFrom().emitter(emitter -> { | ||
vertxRequest.vertx().fileSystem().open(FILE, new OpenOptions(), result -> { | ||
if (result.succeeded()) | ||
emitter.complete(result.result()); | ||
else | ||
emitter.fail(result.cause()); | ||
}); | ||
}); | ||
} | ||
|
||
@Path("async-file-partial") | ||
@GET | ||
public Uni<AsyncFile> getAsyncFilePartial(RoutingContext vertxRequest) { | ||
return Uni.createFrom().emitter(emitter -> { | ||
vertxRequest.vertx().fileSystem().open(FILE, new OpenOptions(), result -> { | ||
if (result.succeeded()) { | ||
AsyncFile asyncFile = result.result(); | ||
asyncFile.setReadPos(20); | ||
asyncFile.setReadLength(10); | ||
emitter.complete(asyncFile); | ||
} else | ||
emitter.fail(result.cause()); | ||
}); | ||
}); | ||
} | ||
} |
143 changes: 143 additions & 0 deletions
143
...oyment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileTestCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package io.quarkus.resteasy.reactive.server.test.providers; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
import javax.ws.rs.core.HttpHeaders; | ||
|
||
import org.hamcrest.Matchers; | ||
import org.jboss.resteasy.reactive.FilePart; | ||
import org.jboss.resteasy.reactive.PathPart; | ||
import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
import org.jboss.shrinkwrap.api.spec.JavaArchive; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.quarkus.test.QuarkusUnitTest; | ||
import io.quarkus.test.common.http.TestHTTPResource; | ||
import io.restassured.RestAssured; | ||
|
||
public class FileTestCase { | ||
|
||
private final static String LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n" | ||
+ | ||
"enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor\n" | ||
+ | ||
"in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,\n" | ||
+ | ||
" sunt in culpa qui officia deserunt mollit anim id est laborum.\n" + | ||
"\n" + | ||
""; | ||
private static final String FILE = "src/test/resources/lorem.txt"; | ||
|
||
@TestHTTPResource | ||
URI uri; | ||
|
||
@RegisterExtension | ||
static final QuarkusUnitTest config = new QuarkusUnitTest() | ||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) | ||
.addClasses(FileResource.class, WithWriterInterceptor.class, WriterInterceptor.class)); | ||
|
||
@Test | ||
public void testFiles() throws Exception { | ||
// adjusting expected file size for Windows, whose git checkout will adjust line separators | ||
String content; | ||
if (System.lineSeparator().length() == 2) { | ||
content = LOREM.replace("\n", System.lineSeparator()); | ||
} else { | ||
content = LOREM; | ||
} | ||
String contentLength = String.valueOf(content.length()); | ||
RestAssured.get("/providers/file/file") | ||
.then() | ||
.statusCode(200) | ||
.header(HttpHeaders.CONTENT_LENGTH, contentLength) | ||
.body(Matchers.equalTo(content)); | ||
RestAssured.get("/providers/file/file-partial") | ||
.then() | ||
.statusCode(200) | ||
.header(HttpHeaders.CONTENT_LENGTH, "10") | ||
.body(Matchers.equalTo(content.substring(20, 30))); | ||
RestAssured.get("/providers/file/path") | ||
.then() | ||
.statusCode(200) | ||
.header(HttpHeaders.CONTENT_LENGTH, contentLength) | ||
.body(Matchers.equalTo(content)); | ||
RestAssured.get("/providers/file/path-partial") | ||
.then() | ||
.statusCode(200) | ||
.header(HttpHeaders.CONTENT_LENGTH, "10") | ||
.body(Matchers.equalTo(content.substring(20, 30))); | ||
RestAssured.get("/providers/file/async-file") | ||
.then() | ||
.header(HttpHeaders.CONTENT_LENGTH, Matchers.nullValue()) | ||
.statusCode(200) | ||
.body(Matchers.equalTo(content)); | ||
RestAssured.get("/providers/file/async-file-partial") | ||
.then() | ||
.statusCode(200) | ||
.header(HttpHeaders.CONTENT_LENGTH, "10") | ||
.body(Matchers.equalTo(LOREM.substring(20, 30))); | ||
} | ||
|
||
@Test | ||
public void testChecks() throws IOException { | ||
// creation-time checks | ||
Path path = Paths.get(FILE); | ||
// works | ||
new PathPart(path, 10, 10); | ||
new PathPart(path, 0, Files.size(path)); | ||
// fails | ||
try { | ||
new PathPart(path, -1, 10); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new PathPart(path, 0, -1); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new PathPart(path, 0, 1000); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new PathPart(path, 250, 250); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
|
||
File file = new File(FILE); | ||
// works | ||
new FilePart(file, 10, 10); | ||
new FilePart(file, 0, file.length()); | ||
// fails | ||
try { | ||
new FilePart(file, -1, 10); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new FilePart(file, 0, -1); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new FilePart(file, 0, 1000); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
try { | ||
new FilePart(file, 250, 250); | ||
Assertions.fail(); | ||
} catch (IllegalArgumentException x) { | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...src/test/java/io/quarkus/resteasy/reactive/server/test/providers/InvalidFileResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.quarkus.resteasy.reactive.server.test.providers; | ||
|
||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
|
||
import io.vertx.core.file.AsyncFile; | ||
import io.vertx.ext.web.RoutingContext; | ||
|
||
@Path("providers/file-invalid") | ||
public class InvalidFileResource { | ||
|
||
@WithWriterInterceptor | ||
@Path("async-file-blocking") | ||
@GET | ||
public AsyncFile getAsyncFileBlocking(RoutingContext vertxRequest) { | ||
// we're not calling this anyway | ||
return null; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...src/test/java/io/quarkus/resteasy/reactive/server/test/providers/InvalidFileTestCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.quarkus.resteasy.reactive.server.test.providers; | ||
|
||
import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
import org.jboss.shrinkwrap.api.spec.JavaArchive; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.quarkus.test.QuarkusUnitTest; | ||
|
||
public class InvalidFileTestCase { | ||
|
||
@RegisterExtension | ||
static final QuarkusUnitTest config = new QuarkusUnitTest() | ||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) | ||
.addClasses(InvalidFileResource.class, WithWriterInterceptor.class, WriterInterceptor.class)) | ||
.assertException(t -> { | ||
while (t.getCause() != null) | ||
t = t.getCause(); | ||
Assertions.assertTrue( | ||
t.getMessage().equals("Endpoints that return an AsyncFile cannot have any WriterInterceptor set")); | ||
}); | ||
|
||
@Test | ||
public void test() throws Exception { | ||
Assertions.fail("Deployment should have failed"); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...c/test/java/io/quarkus/resteasy/reactive/server/test/providers/WithWriterInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.quarkus.resteasy.reactive.server.test.providers; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import javax.ws.rs.NameBinding; | ||
|
||
@NameBinding | ||
@Target({ ElementType.METHOD, ElementType.TYPE }) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface WithWriterInterceptor { | ||
|
||
} |
Oops, something went wrong.