Skip to content

Commit

Permalink
Keep AppendBuffer and VertxServletOutputStream in sync with the origi…
Browse files Browse the repository at this point in the history
…nals in Quarkus fix quarkiverse#1111
  • Loading branch information
ppalaga committed Nov 19, 2023
1 parent 9eb23aa commit bbe9de8
Show file tree
Hide file tree
Showing 9 changed files with 889 additions and 43 deletions.
26 changes: 26 additions & 0 deletions extensions/core/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<executions>
<execution>
<id>sync-quarkus-classes</id>
<goals>
<goal>execute</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<source>file:${maven.multiModuleProjectDirectory}/src/build/scripts/sync-quarkus-classes.groovy</source>
<properties>
</properties>
</configuration>
</execution>
<execution>
<id>filter-and-move-config-options-docs</id>
<goals>
Expand All @@ -144,6 +156,20 @@
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>io.quarkus.resteasy.reactive</groupId>
<artifactId>resteasy-reactive-vertx</artifactId>
<type>jar</type>
<classifier>sources</classifier>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-symbol-solver-core</artifactId>
<version>${javaparser.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,24 @@
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;

import io.vertx.core.http.HttpServerRequest;
import io.quarkiverse.cxf.transport.generated.VertxServletOutputStream;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.RoutingContext;

public class VertxHttpServletResponse implements HttpServletResponse {
protected final RoutingContext context;
private final HttpServerRequest request;
protected final HttpServerResponse response;
private final int outputBufferSize;
private final int minChunkSize;
private VertxServletOutputStream os;
private PrintWriter printWriter;

public VertxHttpServletResponse(RoutingContext context, int outputBufferSize, int minChunkSize) {
this.request = context.request();
this.response = context.response();
this.context = context;
this.outputBufferSize = outputBufferSize;
this.minChunkSize = minChunkSize;
this.os = new VertxServletOutputStream(request, response, context, outputBufferSize, minChunkSize);
this.os = new VertxServletOutputStream(new VertxReactiveRequestContext(context, minChunkSize, outputBufferSize));
}

@Override
Expand Down Expand Up @@ -191,7 +189,7 @@ public void resetBuffer() {
} catch (IOException e) {
}
}
os = new VertxServletOutputStream(request, response, context, outputBufferSize, minChunkSize);
os = new VertxServletOutputStream(new VertxReactiveRequestContext(context, minChunkSize, outputBufferSize));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.quarkiverse.cxf.transport;

import io.vertx.ext.web.RoutingContext;

public class VertxReactiveRequestContext {
private final RoutingContext context;
private final Deployment deployment;

public VertxReactiveRequestContext(
RoutingContext context,
int minChunkSize,
int outputBufferSize) {
super();
this.context = context;
this.deployment = new Deployment(minChunkSize, outputBufferSize);
}

public Deployment getDeployment() {
return deployment;
}

public RoutingContext getContext() {
return context;
}

public static class Deployment {

private final ResteasyReactiveConfig resteasyReactiveConfig;

public Deployment(int minChunkSize, int outputBufferSize) {
super();
this.resteasyReactiveConfig = new ResteasyReactiveConfig(minChunkSize, outputBufferSize);
}

public ResteasyReactiveConfig getResteasyReactiveConfig() {
return resteasyReactiveConfig;
}

}

public static class ResteasyReactiveConfig {
private final int minChunkSize;
private final int outputBufferSize;

public ResteasyReactiveConfig(int minChunkSize, int outputBufferSize) {
super();
this.minChunkSize = minChunkSize;
this.outputBufferSize = outputBufferSize;
}

public int getOutputBufferSize() {
return outputBufferSize;
}

public int getMinChunkSize() {
return minChunkSize;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
package io.quarkiverse.cxf.transport;
package io.quarkiverse.cxf.transport.generated;

import java.util.ArrayDeque;
import java.util.Objects;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.CompositeByteBuf;

/**
* Adapted from
* Adapted by sync-quarkus-classes.groovy from
* <a href=
* "independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/AppendBuffer.java"><code>AppendBuffer</code></a>
* 'https://github.com/quarkusio/quarkus/blob/main/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java'><code>ResteasyReactiveOutputStream</code></a>
* from Quarkus.
*
* It is a bounded (direct) buffer container that can keep on accepting data till {@link #capacity} is exhausted.<br>
* In order to keep appending on it, it can {@link #clear} and consolidate its content as a {@link ByteBuf}.
* <p>
*
* It is a bounded (direct) buffer container that can keep on accepting data till {@link #capacity} is exhausted.<br>
* In order to keep appending on it, it can {@link #clear} and consolidate its content as a {@link ByteBuf}.
*/
final class AppendBuffer {

private final ByteBufAllocator allocator;

private final int minChunkSize;

private final int capacity;

private ByteBuf buffer;

private ArrayDeque<ByteBuf> otherBuffers;

private int size;

private AppendBuffer(ByteBufAllocator allocator, int minChunkSize, int capacity) {
Expand Down Expand Up @@ -193,5 +199,4 @@ public int capacity() {
public int availableCapacity() {
return capacity - size;
}

}
Original file line number Diff line number Diff line change
@@ -1,61 +1,59 @@
package io.quarkiverse.cxf.transport;
package io.quarkiverse.cxf.transport.generated;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;

import org.jboss.logging.Logger;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.quarkiverse.cxf.transport.VertxReactiveRequestContext;
import io.quarkus.vertx.core.runtime.VertxBufferImpl;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.RoutingContext;

/**
* Adapted from
* Adapted by sync-quarkus-classes.groovy from
* <a href=
* "https://github.com/quarkusio/quarkus/blob/b9766f547d2c5c02715b5e35fda1c5f2f15904d8/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java"><code>ResteasyReactiveOutputStream</code></a>
* 'https://github.com/quarkusio/quarkus/blob/main/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java'><code>ResteasyReactiveOutputStream</code></a>
* from Quarkus.
*/
public class VertxServletOutputStream extends ServletOutputStream {

private static final Logger log = Logger.getLogger(VertxServletOutputStream.class);
private static final Logger log = Logger.getLogger("org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveOutputStream");

private final HttpServerRequest request;
private final HttpServerResponse response;
private final VertxReactiveRequestContext context;

protected final HttpServerRequest request;

private final AppendBuffer appendBuffer;

private boolean committed;

private boolean closed;

protected boolean waitingForDrain;

protected boolean drainHandlerRegistered;

protected boolean first = true;

protected Throwable throwable;

private ByteArrayOutputStream overflow;

public VertxServletOutputStream(
HttpServerRequest request,
HttpServerResponse response,
RoutingContext context,
int outputBufferSize,
int minChunkSize) {
this.request = request;
this.response = response;
this.appendBuffer = AppendBuffer.withMinChunks(PooledByteBufAllocator.DEFAULT,
minChunkSize,
outputBufferSize);
public VertxServletOutputStream(VertxReactiveRequestContext context) {
this.context = context;
this.request = context.getContext().request();
this.appendBuffer = AppendBuffer.withMinChunks(PooledByteBufAllocator.DEFAULT, context.getDeployment().getResteasyReactiveConfig().getMinChunkSize(), context.getDeployment().getResteasyReactiveConfig().getOutputBufferSize());
request.response().exceptionHandler(new Handler<Throwable>() {

@Override
public void handle(Throwable event) {
throwable = event;
Expand All @@ -70,8 +68,8 @@ public void handle(Throwable event) {
}
}
});
context.getContext().addEndHandler(new Handler<AsyncResult<Void>>() {

context.addEndHandler(new Handler<AsyncResult<Void>>() {
@Override
public void handle(AsyncResult<Void> event) {
synchronized (request.connection()) {
Expand All @@ -85,7 +83,6 @@ public void handle(AsyncResult<Void> event) {
}

public void terminateResponse() {

}

Buffer createBuffer(ByteBuf data) {
Expand Down Expand Up @@ -165,6 +162,7 @@ private void registerDrainHandler() {
if (!drainHandlerRegistered) {
drainHandlerRegistered = true;
Handler<Void> handler = new Handler<Void>() {

@Override
public void handle(Void event) {
synchronized (request.connection()) {
Expand Down Expand Up @@ -192,31 +190,27 @@ public void handle(Void event) {
/**
* {@inheritDoc}
*/
@Override
public void write(final int b) throws IOException {
write(new byte[] { (byte) b }, 0, 1);
}

/**
* {@inheritDoc}
*/
@Override
public void write(final byte[] b) throws IOException {
write(b, 0, b.length);
}

/**
* {@inheritDoc}
*/
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
if (len < 1) {
return;
}
if (closed) {
throw new IOException("Stream is closed");
}

int rem = len;
int idx = off;
try {
Expand All @@ -242,11 +236,12 @@ private void prepareWrite(ByteBuf buffer, boolean finished) throws IOException {
if (!committed) {
committed = true;
if (finished) {
final HttpServerResponse response = request.response();
if (!response.headWritten()) {
if (buffer == null) {
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, "0");
} else {
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, "" + buffer.readableBytes());
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(buffer.readableBytes()));
}
}
} else {
Expand All @@ -258,7 +253,6 @@ private void prepareWrite(ByteBuf buffer, boolean finished) throws IOException {
/**
* {@inheritDoc}
*/
@Override
public void flush() throws IOException {
if (closed) {
throw new IOException("Stream is closed");
Expand All @@ -276,7 +270,6 @@ public void flush() throws IOException {
/**
* {@inheritDoc}
*/
@Override
public void close() throws IOException {
if (closed)
return;
Expand All @@ -298,5 +291,4 @@ public boolean isReady() {
public void setWriteListener(WriteListener writeListener) {
throw new UnsupportedOperationException();
}

}
21 changes: 21 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@

<supported-maven.versions>[3.6.2,)</supported-maven.versions>

<!-- Build time dependencies -->
<javaparser.version>3.25.6</javaparser.version>

<cq-maven-plugin.version>4.4.7</cq-maven-plugin.version>
<groovy-maven-plugin.version>2.1.1</groovy-maven-plugin.version>
<groovy.version>3.0.19</groovy.version>
Expand Down Expand Up @@ -336,6 +339,24 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<configuration>
<excludes><!-- Do not format generated files -->
<exclude>**/generated/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>impsort-maven-plugin</artifactId>
<configuration>
<excludes><!-- Do not format generated files -->
<exclude>**/generated/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Loading

0 comments on commit bbe9de8

Please sign in to comment.