diff --git a/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/HttpEndpointRequestHandler.java b/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/HttpEndpointRequestHandler.java index aeff003e..1ff88269 100644 --- a/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/HttpEndpointRequestHandler.java +++ b/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/HttpEndpointRequestHandler.java @@ -30,6 +30,7 @@ import org.apache.logging.log4j.Logger; import org.jspecify.annotations.Nullable; +/** Vert.x HttpServer handler adapter for {@link Endpoint}. See {@link #fromEndpoint(Endpoint)}. */ public class HttpEndpointRequestHandler implements Handler { private static final Logger LOG = LogManager.getLogger(HttpEndpointRequestHandler.class); diff --git a/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/RestateHttpServer.java b/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/RestateHttpServer.java index 4dba06aa..33c41205 100644 --- a/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/RestateHttpServer.java +++ b/sdk-http-vertx/src/main/java/dev/restate/sdk/http/vertx/RestateHttpServer.java @@ -90,9 +90,7 @@ public static int listen(HttpEndpointRequestHandler requestHandler) { /** Like {@link #listen(Endpoint, int)}, with an already built request handler */ public static int listen(HttpEndpointRequestHandler requestHandler, int port) { - HttpServer server = Vertx.vertx().createHttpServer(DEFAULT_OPTIONS); - server.requestHandler(requestHandler); - return handleStart(server.listen(port)); + return handleStart(fromHandler(requestHandler).listen(port)); } /** Create a Vert.x {@link HttpServer} from the provided endpoint. */ @@ -134,9 +132,7 @@ public static HttpServer fromEndpoint(Vertx vertx, Endpoint.Builder endpointBuil * HttpServerOptions}. */ public static HttpServer fromEndpoint(Vertx vertx, Endpoint endpoint, HttpServerOptions options) { - HttpServer server = vertx.createHttpServer(options); - server.requestHandler(HttpEndpointRequestHandler.fromEndpoint(endpoint)); - return server; + return fromHandler(vertx, HttpEndpointRequestHandler.fromEndpoint(endpoint), options); } /** Like {@link #fromEndpoint(Vertx, Endpoint, HttpServerOptions)} */ @@ -145,6 +141,36 @@ public static HttpServer fromEndpoint( return fromEndpoint(vertx, endpointBuilder.build(), options); } + /** Create a Vert.x {@link HttpServer} from the provided {@link HttpEndpointRequestHandler}. */ + public static HttpServer fromHandler(HttpEndpointRequestHandler handler) { + return fromHandler(handler, DEFAULT_OPTIONS); + } + + /** + * Create a Vert.x {@link HttpServer} from the provided {@link HttpEndpointRequestHandler}, with + * the given {@link HttpServerOptions}. + */ + public static HttpServer fromHandler( + HttpEndpointRequestHandler handler, HttpServerOptions options) { + return fromHandler(Vertx.vertx(), handler, options); + } + + /** Create a Vert.x {@link HttpServer} from the provided {@link HttpEndpointRequestHandler}. */ + public static HttpServer fromHandler(Vertx vertx, HttpEndpointRequestHandler handler) { + return fromHandler(vertx, handler, DEFAULT_OPTIONS); + } + + /** + * Create a Vert.x {@link HttpServer} from the provided {@link HttpEndpointRequestHandler}, with + * the given {@link HttpServerOptions}. + */ + public static HttpServer fromHandler( + Vertx vertx, HttpEndpointRequestHandler handler, HttpServerOptions options) { + HttpServer server = vertx.createHttpServer(options); + server.requestHandler(handler); + return server; + } + private static int handleStart(Future fut) { try { HttpServer server = fut.toCompletionStage().toCompletableFuture().join(); diff --git a/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpEndpointBean.java b/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpEndpointBean.java index 6757f999..32f8535f 100644 --- a/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpEndpointBean.java +++ b/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpEndpointBean.java @@ -10,6 +10,7 @@ import dev.restate.sdk.auth.signing.RestateRequestIdentityVerifier; import dev.restate.sdk.endpoint.Endpoint; +import dev.restate.sdk.http.vertx.HttpEndpointRequestHandler; import dev.restate.sdk.http.vertx.RestateHttpServer; import io.vertx.core.http.HttpServer; import java.util.Map; @@ -74,7 +75,11 @@ public void afterPropertiesSet() { RestateRequestIdentityVerifier.fromKey(restateEndpointProperties.getIdentityKey())); } - this.server = RestateHttpServer.fromEndpoint(builder.build()); + this.server = + RestateHttpServer.fromHandler( + HttpEndpointRequestHandler.fromEndpoint( + builder.build(), + this.restateHttpServerProperties.isDisableBidirectionalStreaming())); } @Override diff --git a/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpServerProperties.java b/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpServerProperties.java index b9a223d5..0baa78de 100644 --- a/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpServerProperties.java +++ b/sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpServerProperties.java @@ -17,14 +17,30 @@ public class RestateHttpServerProperties { private final int port; + private final boolean disableBidirectionalStreaming; @ConstructorBinding - public RestateHttpServerProperties(@Name("port") @DefaultValue(value = "9080") int port) { + public RestateHttpServerProperties( + @Name("port") @DefaultValue(value = "9080") int port, + @Name("disableBidirectionalStreaming") @DefaultValue(value = "false") + boolean disableBidirectionalStreaming) { this.port = port; + this.disableBidirectionalStreaming = disableBidirectionalStreaming; } /** Port to expose the HTTP server. */ public int getPort() { return port; } + + /** + * If true, disable bidirectional streaming with HTTP/2 requests. Restate initiates for each + * invocation a bidirectional streaming using HTTP/2 between restate-server and the SDK. In some + * network setups, for example when using a load balancers that buffer request/response, + * bidirectional streaming will not work correctly. Only in these scenarios, we suggest disabling + * bidirectional streaming. + */ + public boolean isDisableBidirectionalStreaming() { + return disableBidirectionalStreaming; + } }