Repository: cxf Updated Branches: refs/heads/master b003f35e6 -> b62ea1115
[CXF-6882] Making the error handlers optional Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b62ea111 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b62ea111 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b62ea111 Branch: refs/heads/master Commit: b62ea11153d17a5849ef4242842f22ca996ce2a1 Parents: b003f35 Author: Sergey Beryozkin <sberyoz...@gmail.com> Authored: Thu Aug 10 13:53:19 2017 +0100 Committer: Sergey Beryozkin <sberyoz...@gmail.com> Committed: Thu Aug 10 13:53:19 2017 +0100 ---------------------------------------------------------------------- .../org/apache/cxf/jaxrs/nio/NioReadEntity.java | 21 ++--- .../apache/cxf/jaxrs/nio/NioReadHandler.java | 4 +- .../cxf/jaxrs/nio/NioReadListenerImpl.java | 29 +++++-- .../apache/cxf/jaxrs/nio/NioWriteEntity.java | 4 + .../apache/cxf/jaxrs/nio/NioWriteHandler.java | 4 +- .../cxf/jaxrs/nio/NioWriteListenerImpl.java | 6 +- .../cxf/systest/jaxrs/nio/NioBookStore.java | 86 +++++++++++--------- 7 files changed, 94 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java index 2dde9ae..40b1901 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadEntity.java @@ -18,9 +18,8 @@ */ package org.apache.cxf.jaxrs.nio; -import java.io.IOException; - import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.AsyncResponse; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.message.Message; @@ -30,23 +29,25 @@ public class NioReadEntity { private final NioReadHandler reader; private final NioReadCompletionHandler completion; private final NioErrorHandler error; - + public NioReadEntity(NioReadHandler reader, NioReadCompletionHandler completion) { + this(reader, completion, null); + } public NioReadEntity(NioReadHandler reader, NioReadCompletionHandler completion, NioErrorHandler error) { this.reader = reader; this.completion = completion; this.error = error; + final Message m = JAXRSUtils.getCurrentMessage(); try { - final Message m = JAXRSUtils.getCurrentMessage(); - if (m != null) { - final HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST); - if (request != null) { - request.getInputStream().setReadListener(new NioReadListenerImpl(this, request.getInputStream())); - } + if (m.get(AsyncResponse.class) == null) { + throw new IllegalStateException("AsyncResponse is not available"); } - } catch (final IOException ex) { + final HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST); + request.getInputStream().setReadListener(new NioReadListenerImpl(this, request.getInputStream())); + } catch (final Throwable ex) { throw new RuntimeException("Unable to initialize NIO entity", ex); } + } public NioReadHandler getReader() { http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadHandler.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadHandler.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadHandler.java index b5c6674..c26a4ea 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadHandler.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadHandler.java @@ -18,6 +18,8 @@ */ package org.apache.cxf.jaxrs.nio; +import java.io.IOException; + /** * Class NioReader. */ @@ -30,6 +32,6 @@ public interface NioReadHandler { * * @param in input stream. */ - void read(NioInputStream in); + void read(NioInputStream in) throws IOException; } http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java index a090c5f..2741cf7 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioReadListenerImpl.java @@ -23,9 +23,11 @@ import java.util.logging.Logger; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; +import javax.ws.rs.container.AsyncResponse; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.jaxrs.utils.ExceptionUtils; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; public final class NioReadListenerImpl implements ReadListener { private static final Logger LOG = LogUtils.getL7dLogger(NioReadListenerImpl.class); @@ -38,15 +40,6 @@ public final class NioReadListenerImpl implements ReadListener { } @Override - public void onError(Throwable t) { - try { - entity.getError().error(t); - } catch (final Throwable ex) { - LOG.warning("NIO NioReadListener error: " + ExceptionUtils.getStackTrace(ex)); - } - } - - @Override public void onDataAvailable() throws IOException { while (in.isReady() && !in.isFinished()) { entity.getReader().read(in); @@ -57,4 +50,22 @@ public final class NioReadListenerImpl implements ReadListener { public void onAllDataRead() throws IOException { entity.getCompletion().complete(); } + + @Override + public void onError(Throwable t) { + if (entity.getError() == null) { + getAsyncResponse().resume(t); + return; + } + try { + entity.getError().error(t); + } catch (final Throwable ex) { + LOG.warning("NIO NioReadListener error: " + ExceptionUtils.getStackTrace(ex)); + } + } + + private AsyncResponse getAsyncResponse() { + return JAXRSUtils.getCurrentMessage().getExchange().get(AsyncResponse.class); + } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteEntity.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteEntity.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteEntity.java index 32874e3..64e5281 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteEntity.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteEntity.java @@ -22,6 +22,10 @@ public final class NioWriteEntity { private final NioWriteHandler writer; private final NioErrorHandler error; + public NioWriteEntity(final NioWriteHandler writer) { + this(writer, null); + } + public NioWriteEntity(final NioWriteHandler writer, final NioErrorHandler error) { this.writer = writer; this.error = error; http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteHandler.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteHandler.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteHandler.java index 8d26589..6130076 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteHandler.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteHandler.java @@ -18,6 +18,8 @@ */ package org.apache.cxf.jaxrs.nio; +import java.io.IOException; + /** * Class NioWriterHandler. */ @@ -29,6 +31,6 @@ public interface NioWriteHandler { * @param out output stream. * @return {@code true} if there is more data to write, {@code false} otherwise. */ - boolean write(NioOutputStream out); + boolean write(NioOutputStream out) throws IOException; } http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteListenerImpl.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteListenerImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteListenerImpl.java index d20133f..95447d4 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteListenerImpl.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/nio/NioWriteListenerImpl.java @@ -53,7 +53,11 @@ public final class NioWriteListenerImpl implements WriteListener { @Override public void onError(Throwable t) { try { - entity.getError().error(t); + if (entity.getError() != null) { + entity.getError().error(t); + } else { + throw t; + } } catch (final Throwable ex) { LOG.warning("NIO WriteListener error: " + ExceptionUtils.getStackTrace(ex)); } finally { http://git-wip-us.apache.org/repos/asf/cxf/blob/b62ea111/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java index d98cfdc..3cba5c4 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/nio/NioBookStore.java @@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.util.concurrent.atomic.LongAdder; import javax.ws.rs.Consumes; @@ -29,12 +30,9 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; -import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import org.apache.cxf.annotations.UseNio; @@ -46,7 +44,7 @@ import org.apache.cxf.jaxrs.nio.NioWriteEntity; public class NioBookStore { @GET @Produces(MediaType.TEXT_PLAIN) - public Response readBooks() throws IOException { + public Response getBookStream() throws IOException { final ByteArrayInputStream in = new ByteArrayInputStream( IOUtils.readBytesFromStream(getClass().getResourceAsStream("/files/books.txt"))); final byte[] buffer = new byte[4096]; @@ -56,28 +54,24 @@ public class NioBookStore { .entity( new NioWriteEntity( out -> { - try { - final int n = in.read(buffer); - - if (n >= 0) { - out.write(buffer, 0, n); - return true; - } - - try { - in.close(); - } catch (IOException ex) { - /* do nothing */ - } - - return false; - } catch (IOException ex) { - throw new WebApplicationException(ex); + final int n = in.read(buffer); + + if (n >= 0) { + out.write(buffer, 0, n); + return true; } - }, - throwable -> { - throw throwable; + + closeInputStream(in); + + return false; } + // by default the runtime will throw the exception itself + // if the error handler is not provided + + //, + //throwable -> { + // throw throwable; + //} )) .build(); } @@ -86,14 +80,14 @@ public class NioBookStore { @Produces(MediaType.TEXT_PLAIN) @Path("/is") @UseNio - public InputStream readBooksFromInputStream() throws IOException { + public InputStream getBookStreamFromInputStream() throws IOException { return getClass().getResourceAsStream("/files/books.txt"); } @POST @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.TEXT_PLAIN) - public void uploadBooks(@Context Request request, @Suspended AsyncResponse response) { + public void uploadBookStream(@Suspended AsyncResponse response) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); final byte[] buffer = new byte[4096]; final LongAdder adder = new LongAdder(); @@ -101,24 +95,40 @@ public class NioBookStore { new NioReadEntity( // read handler in -> { - try { - final int n = in.read(buffer); - if (n > 0) { - adder.add(n); - out.write(buffer, 0, n); - } - } catch (IOException e) { - response.resume(new WebApplicationException(e)); + final int n = in.read(buffer); + if (n > 0) { + adder.add(n); + out.write(buffer, 0, n); } }, // completion handler () -> { + closeOutputStream(out); response.resume("Book Store uploaded: " + adder.longValue() + " bytes"); - }, - // error handler - t -> { - response.resume(t); } + // by default the runtime will resume AsyncResponse with Throwable itself + // if the error handler is not provided + + //, + // error handler + //t -> { + // response.resume(t); + //} ); } + + private static void closeInputStream(InputStream in) { + try { + in.close(); + } catch (IOException ex) { + /* do nothing */ + } + } + private static void closeOutputStream(OutputStream out) { + try { + out.close(); + } catch (IOException ex) { + /* do nothing */ + } + } }