diff --git a/.circleci/config.yml b/.circleci/config.yml index b37b6814..1c473006 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ version: 2.1 setup: true orbs: - gravitee: gravitee-io/gravitee@4.1.1 + gravitee: gravitee-io/gravitee@4.8.0 # our single workflow, that triggers the setup job defined above, filters on tag and branches are needed otherwise # some workflow and job will not be triggered for tags (default CircleCI behavior) diff --git a/CHANGELOG.md b/CHANGELOG.md index e236fbff..c089c76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# [5.0.0-alpha.3](https://github.com/gravitee-io/gravitee-connector-http/compare/5.0.0-alpha.2...5.0.0-alpha.3) (2024-12-30) + + +### Bug Fixes + +* **deps:** use apim latest alpha ([4e4b16f](https://github.com/gravitee-io/gravitee-connector-http/commit/4e4b16f1d59495643dfda3ff0b75667d8ac2721b)) + +# [5.0.0-alpha.2](https://github.com/gravitee-io/gravitee-connector-http/compare/5.0.0-alpha.1...5.0.0-alpha.2) (2024-12-20) + + +### Bug Fixes + +* avoid some NPE when connection has failed ([b652a34](https://github.com/gravitee-io/gravitee-connector-http/commit/b652a34fed9f710a7262ff85f212793de79dff2c)) + +# [5.0.0-alpha.1](https://github.com/gravitee-io/gravitee-connector-http/compare/4.0.4-alpha.1...5.0.0-alpha.1) (2024-11-06) + + +### Features + +* support new OpenTelemetry feature ([54672dd](https://github.com/gravitee-io/gravitee-connector-http/commit/54672ddff7a6fdcd20ee0138f45feafe5da54a44)) + + +### BREAKING CHANGES + +* Tracing plugin has been removed and is now embedded inside node framework + +## [4.0.4-alpha.1](https://github.com/gravitee-io/gravitee-connector-http/compare/4.0.3...4.0.4-alpha.1) (2024-10-23) + + +### Bug Fixes + +* revert "reapply ByteBuf optimization" ([633abc5](https://github.com/gravitee-io/gravitee-connector-http/commit/633abc55eb039de9ea0082a3a6a6861b6e6570ed)) + ## [4.0.4](https://github.com/gravitee-io/gravitee-connector-http/compare/4.0.3...4.0.4) (2024-12-12) diff --git a/pom.xml b/pom.xml index 726b6e26..734008fc 100644 --- a/pom.xml +++ b/pom.xml @@ -29,17 +29,12 @@ io.gravitee.connector gravitee-connector-http - 4.0.4 + 5.0.0-alpha.3 Gravitee.io - Connector - HTTP - 7.0.14 - 4.0.0 - 1.1.5 - 3.5.0 - 3.1.0 - 5.11.0 + 4.6.0-alpha.3 3.7.1 @@ -50,17 +45,12 @@ - io.gravitee - gravitee-bom - ${gravitee-bom.version} + io.gravitee.apim + gravitee-apim-bom + ${gravitee-apim.version} import pom - - io.gravitee.gateway - gravitee-gateway-api - ${gravitee-gateway-api.version} - @@ -68,35 +58,30 @@ io.gravitee.common gravitee-common - ${gravitee-common.version} provided io.gravitee.connector gravitee-connector-api - ${gravitee-connector-api.version} provided io.gravitee.el gravitee-expression-language - ${gravitee-expression-language.version} provided io.gravitee.node gravitee-node-api - ${gravitee-node.version} provided io.gravitee.node gravitee-node-vertx - ${gravitee-node.version} provided @@ -123,7 +108,12 @@ io.gravitee.apim.gateway gravitee-apim-gateway-buffer - 4.0.25 + ${gravitee-apim.version} + test + + + io.gravitee.node + gravitee-node-opentelemetry test diff --git a/src/main/java/io/gravitee/connector/http/AbstractHttpConnection.java b/src/main/java/io/gravitee/connector/http/AbstractHttpConnection.java index 21441bb9..44b8c311 100644 --- a/src/main/java/io/gravitee/connector/http/AbstractHttpConnection.java +++ b/src/main/java/io/gravitee/connector/http/AbstractHttpConnection.java @@ -17,6 +17,7 @@ import io.gravitee.connector.api.Response; import io.gravitee.connector.http.endpoint.HttpEndpoint; +import io.gravitee.gateway.api.ExecutionContext; import io.gravitee.gateway.api.handler.Handler; import io.vertx.core.http.HttpClient; @@ -33,6 +34,7 @@ public AbstractHttpConnection(E endpoint) { } public abstract void connect( + final ExecutionContext context, HttpClient httpClient, int port, String host, diff --git a/src/main/java/io/gravitee/connector/http/AbstractHttpConnector.java b/src/main/java/io/gravitee/connector/http/AbstractHttpConnector.java index b6f32dc1..00972111 100644 --- a/src/main/java/io/gravitee/connector/http/AbstractHttpConnector.java +++ b/src/main/java/io/gravitee/connector/http/AbstractHttpConnector.java @@ -39,7 +39,13 @@ import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpVersion; -import io.vertx.core.net.*; +import io.vertx.core.net.JksOptions; +import io.vertx.core.net.OpenSSLEngineOptions; +import io.vertx.core.net.PemKeyCertOptions; +import io.vertx.core.net.PemTrustOptions; +import io.vertx.core.net.PfxOptions; +import io.vertx.core.net.ProxyOptions; +import io.vertx.core.net.ProxyType; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; @@ -133,6 +139,7 @@ public void request(ExecutionContext context, ProxyRequest request, Handler connectionHandler, Handler tracker) { + public void connect( + final ExecutionContext ctx, + HttpClient httpClient, + int port, + String host, + String uri, + Handler connectionHandler, + Handler tracker + ) { // Remove HOP-by-HOP headers for (CharSequence header : HOP_HEADERS) { request.headers().remove(header.toString()); @@ -95,48 +111,50 @@ public void connect(HttpClient httpClient, int port, String host, String uri, Ha request.headers().remove(io.gravitee.common.http.HttpHeaders.ACCEPT_ENCODING); } - Future requestFuture = prepareUpstreamRequest(httpClient, port, host, uri); - requestFuture.onComplete( - new io.vertx.core.Handler<>() { - @Override - public void handle(AsyncResult event) { - cancelHandler(tracker); - - if (event.succeeded()) { - httpClientRequest = event.result(); - - httpClientRequest.response(response -> { - // Prepare upstream response - handleUpstreamResponse(response, tracker); - }); - - httpClientRequest - .connection() - .exceptionHandler(t -> { - LOGGER.debug( - "Exception occurs during HTTP connection for api [{}] & request id [{}]: {}", - request.metrics().getApi(), - request.metrics().getRequestId(), - t.getMessage() - ); - request.metrics().setMessage(t.getMessage()); - }); - - httpClientRequest.exceptionHandler(exEvent -> { - if (!isCanceled() && !isTransmitted()) { - handleException(event.cause()); - tracker.handle(null); - } - }); - connectionHandler.handle(null); - } else { - connectionHandler.handle(null); + RequestOptions requestOptions = prepareRequestOptions(port, host, uri); + ObservableHttpClientRequest observableHttpClientRequest = new ObservableHttpClientRequest(requestOptions); + Span requestSpan = ctx.getTracer().startSpanFrom(observableHttpClientRequest); + Future requestFuture = prepareUpstreamRequest(httpClient, requestOptions); + requestFuture.onComplete(event -> { + cancelHandler(tracker); + + if (event.succeeded()) { + httpClientRequest = event.result(); + observableHttpClientRequest.httpClientRequest(httpClientRequest); + + httpClientRequest.response(response -> { + // Prepare upstream response + handleUpstreamResponse(ctx, response, tracker, requestSpan); + }); + + httpClientRequest + .connection() + .exceptionHandler(t -> { + ctx.getTracer().endOnError(requestSpan, t); + LOGGER.debug( + "Exception occurs during HTTP connection for api [{}] & request id [{}]: {}", + request.metrics().getApi(), + request.metrics().getRequestId(), + t.getMessage() + ); + request.metrics().setMessage(t.getMessage()); + }); + + httpClientRequest.exceptionHandler(exEvent -> { + ctx.getTracer().endOnError(requestSpan, event.cause()); + if (!isCanceled() && !isTransmitted()) { handleException(event.cause()); tracker.handle(null); } - } + }); + connectionHandler.handle(null); + } else { + ctx.getTracer().endOnError(requestSpan, event.cause()); + connectionHandler.handle(null); + handleException(event.cause()); + tracker.handle(null); } - ); + }); } private void handleException(Throwable cause) { @@ -163,27 +181,34 @@ private void handleException(Throwable cause) { } } - protected Future prepareUpstreamRequest(HttpClient httpClient, int port, String host, String uri) { + protected RequestOptions prepareRequestOptions(int port, String host, String uri) { + return new RequestOptions() + .setHost(host) + .setMethod(HttpMethod.valueOf(request.method().name())) + .setPort(port) + .setURI(uri) + .setTimeout(endpoint.getHttpClientOptions().getReadTimeout()) + .setFollowRedirects(endpoint.getHttpClientOptions().isFollowRedirects()); + } + + protected Future prepareUpstreamRequest(HttpClient httpClient, RequestOptions requestOptions) { // Prepare HTTP request - return httpClient.request( - new RequestOptions() - .setHost(host) - .setMethod(HttpMethod.valueOf(request.method().name())) - .setPort(port) - .setURI(uri) - .setTimeout(endpoint.getHttpClientOptions().getReadTimeout()) - .setFollowRedirects(endpoint.getHttpClientOptions().isFollowRedirects()) - ); + return httpClient.request(requestOptions); } protected T createProxyResponse(HttpClientResponse clientResponse) { return (T) new HttpResponse(clientResponse); } - protected T handleUpstreamResponse(final AsyncResult clientResponseFuture, Handler tracker) { + protected T handleUpstreamResponse( + final ExecutionContext ctx, + final AsyncResult clientResponseFuture, + Handler tracker, + final Span requestSpan + ) { if (clientResponseFuture.succeeded()) { HttpClientResponse clientResponse = clientResponseFuture.result(); - + ctx.getTracer().endWithResponse(requestSpan, new ObservableHttpClientResponse(clientResponse)); response = createProxyResponse(clientResponse); if (isSse(request)) { @@ -198,7 +223,7 @@ protected T handleUpstreamResponse(final AsyncResult clientR response.cancelHandler(tracker); // Copy body content - clientResponse.handler(event -> response.bodyHandler().handle(Buffer.buffer(event))); + clientResponse.handler(event -> response.bodyHandler().handle(Buffer.buffer(event.getBytes()))); // Signal end of the response clientResponse.endHandler(event -> { @@ -225,6 +250,7 @@ protected T handleUpstreamResponse(final AsyncResult clientR // And send it to the client sendToClient(response); } else { + ctx.getTracer().endWithResponseAndError(requestSpan, clientResponseFuture.result(), clientResponseFuture.cause()); handleException(clientResponseFuture.cause()); tracker.handle(null); } diff --git a/src/main/java/io/gravitee/connector/http/grpc/GrpcConnection.java b/src/main/java/io/gravitee/connector/http/grpc/GrpcConnection.java index cdbc6783..7a21b6c6 100644 --- a/src/main/java/io/gravitee/connector/http/grpc/GrpcConnection.java +++ b/src/main/java/io/gravitee/connector/http/grpc/GrpcConnection.java @@ -40,22 +40,29 @@ public GrpcConnection(HttpEndpoint endpoint, ProxyRequest request) { super(endpoint, request); } + protected RequestOptions prepareRequestOptions( + int port, + String host, + String uri, + final io.gravitee.gateway.api.http.HttpHeaders headers + ) { + return new RequestOptions() + .setHost(host) + .setMethod(HttpMethod.POST) + .setPort(port) + .setURI(uri) + // Ensure required gRPC headers + .putHeader(HttpHeaderNames.CONTENT_TYPE, MediaType.APPLICATION_GRPC) + .putHeader(HttpHeaderNames.TE, GRPC_TRAILERS_TE) + .setTimeout(endpoint.getHttpClientOptions().getReadTimeout()) + .setFollowRedirects(endpoint.getHttpClientOptions().isFollowRedirects()); + } + @Override - protected Future prepareUpstreamRequest(HttpClient httpClient, int port, String host, String uri) { + protected Future prepareUpstreamRequest(HttpClient httpClient, RequestOptions requestOptions) { // Prepare HTTP request return httpClient - .request( - new RequestOptions() - .setHost(host) - .setMethod(HttpMethod.POST) - .setPort(port) - .setURI(uri) - // Ensure required gRPC headers - .putHeader(HttpHeaderNames.CONTENT_TYPE, MediaType.APPLICATION_GRPC) - .putHeader(HttpHeaderNames.TE, GRPC_TRAILERS_TE) - .setTimeout(endpoint.getHttpClientOptions().getReadTimeout()) - .setFollowRedirects(endpoint.getHttpClientOptions().isFollowRedirects()) - ) + .request(requestOptions) .map(httpClientRequest -> { // Always set chunked mode for gRPC transport return httpClientRequest.setChunked(true); diff --git a/src/main/java/io/gravitee/connector/http/ws/WebSocketConnection.java b/src/main/java/io/gravitee/connector/http/ws/WebSocketConnection.java index 9782ceb2..d2cb6250 100644 --- a/src/main/java/io/gravitee/connector/http/ws/WebSocketConnection.java +++ b/src/main/java/io/gravitee/connector/http/ws/WebSocketConnection.java @@ -19,6 +19,7 @@ import io.gravitee.connector.api.response.StatusResponse; import io.gravitee.connector.http.AbstractHttpConnection; import io.gravitee.connector.http.endpoint.HttpEndpoint; +import io.gravitee.gateway.api.ExecutionContext; import io.gravitee.gateway.api.buffer.Buffer; import io.gravitee.gateway.api.handler.Handler; import io.gravitee.gateway.api.proxy.ProxyRequest; @@ -31,7 +32,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import java.util.function.Consumer; /** * @author David BRASSELY (david.brassely at graviteesource.com) @@ -63,7 +63,15 @@ public WebSocketConnection(HttpEndpoint endpoint, ProxyRequest request) { } @Override - public void connect(HttpClient httpClient, int port, String host, String uri, Handler connectionHandler, Handler tracker) { + public void connect( + final ExecutionContext context, + HttpClient httpClient, + int port, + String host, + String uri, + Handler connectionHandler, + Handler tracker + ) { // Remove hop-by-hop headers. for (CharSequence header : WS_HOP_HEADERS) { wsProxyRequest.headers().remove(header); diff --git a/src/test/java/io/gravitee/connector/http/HttpConnectionTest.java b/src/test/java/io/gravitee/connector/http/HttpConnectionTest.java index 06a84870..d732b3d4 100644 --- a/src/test/java/io/gravitee/connector/http/HttpConnectionTest.java +++ b/src/test/java/io/gravitee/connector/http/HttpConnectionTest.java @@ -26,9 +26,12 @@ import io.gravitee.connector.http.endpoint.HttpClientOptions; import io.gravitee.connector.http.endpoint.HttpEndpoint; import io.gravitee.connector.http.stub.DummyHttpClientRequest; +import io.gravitee.gateway.api.ExecutionContext; import io.gravitee.gateway.api.http.HttpHeaderNames; import io.gravitee.gateway.api.http.HttpHeaders; import io.gravitee.gateway.api.proxy.ProxyRequest; +import io.gravitee.gateway.reactive.api.tracing.Tracer; +import io.gravitee.node.opentelemetry.tracer.noop.NoOpTracer; import io.gravitee.reporter.api.http.Metrics; import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; @@ -60,6 +63,9 @@ public class HttpConnectionTest { private HttpConnection cut; + @Mock + private ExecutionContext context; + @Mock private HttpEndpoint endpoint; @@ -91,6 +97,7 @@ public void setUp() { httpClientOptions = new HttpClientOptions(); when(endpoint.getHttpClientOptions()).thenReturn(httpClientOptions); when(client.request(any())).thenReturn(Future.succeededFuture(httpClientRequest)); + when(context.getTracer()).thenReturn(new Tracer(null, new NoOpTracer())); } @Test @@ -100,7 +107,7 @@ public void shouldSetMetricsMessageWithVertxConnectionException() { requestMetrics.setRequestId("request-id"); when(request.metrics()).thenReturn(requestMetrics); - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); // Rely on testing class ThrowingOnGoAwayHttpConnection to make the connection fail and trigger the exceptionHandler we want to test httpClientRequest.connection().goAway(204, 1, Buffer.buffer("💥 Connection error")); @@ -109,7 +116,7 @@ public void shouldSetMetricsMessageWithVertxConnectionException() { @Test public void shouldWriteUpstreamHeaders() { - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); cut.writeUpstreamHeaders(); @@ -121,7 +128,7 @@ public void shouldWriteUpstreamHeaders() { @Test public void shouldWrite() { - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); assertThat(httpClientRequest.headers().get(CONTENT_LENGTH)).isNull(); cut.write(io.gravitee.gateway.api.buffer.Buffer.buffer()); assertThat(httpClientRequest.headers().get(CONTENT_LENGTH)).isEqualTo("0"); @@ -133,7 +140,7 @@ public void shouldPropagateClientAcceptEncodingHeader() { httpClientOptions.setPropagateClientAcceptEncoding(true); headers.set(ACCEPT_ENCODING, BROTLI); - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); cut.writeUpstreamHeaders(); @@ -145,7 +152,7 @@ public void shouldNotPropagateClientAcceptEncodingHeaderWhenNoHeader() { httpClientOptions.setUseCompression(false); httpClientOptions.setPropagateClientAcceptEncoding(true); - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); cut.writeUpstreamHeaders(); @@ -158,7 +165,7 @@ public void shouldNotPropagateClientAcceptEncodingHeaderWhenCompressionIsEnabled httpClientOptions.setPropagateClientAcceptEncoding(true); headers.set(ACCEPT_ENCODING, BROTLI); - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); cut.writeUpstreamHeaders(); @@ -171,7 +178,7 @@ public void shouldNotPropagateClientAcceptEncodingHeaderWhenPropagateIsDisabled( httpClientOptions.setPropagateClientAcceptEncoding(false); headers.set(ACCEPT_ENCODING, BROTLI); - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect(context, client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); cut.writeUpstreamHeaders(); diff --git a/src/test/java/io/gravitee/connector/http/HttpConnectorTest.java b/src/test/java/io/gravitee/connector/http/HttpConnectorTest.java index cfdac6af..7b16b029 100644 --- a/src/test/java/io/gravitee/connector/http/HttpConnectorTest.java +++ b/src/test/java/io/gravitee/connector/http/HttpConnectorTest.java @@ -36,7 +36,9 @@ import io.gravitee.gateway.api.http.HttpHeaders; import io.gravitee.gateway.api.proxy.ProxyRequest; import io.gravitee.gateway.api.proxy.ws.WebSocketProxyRequest; +import io.gravitee.gateway.reactive.api.tracing.Tracer; import io.gravitee.node.api.configuration.Configuration; +import io.gravitee.node.opentelemetry.tracer.noop.NoOpTracer; import io.gravitee.reporter.api.http.Metrics; import io.vertx.core.Future; import io.vertx.core.http.*; @@ -95,6 +97,7 @@ public class HttpConnectorTest { @BeforeEach public void setUp() throws Exception { + lenient().when(executionContext.getTracer()).thenReturn(new Tracer(null, new NoOpTracer())); httpClientsOptions.setConnectTimeout(0L); httpClientsOptions.setReadTimeout(0L); String target = "https://api.gravitee.io/echo"; diff --git a/src/test/java/io/gravitee/connector/http/grpc/GrpcConnectionTest.java b/src/test/java/io/gravitee/connector/http/grpc/GrpcConnectionTest.java index 506d0c65..68feae44 100644 --- a/src/test/java/io/gravitee/connector/http/grpc/GrpcConnectionTest.java +++ b/src/test/java/io/gravitee/connector/http/grpc/GrpcConnectionTest.java @@ -23,9 +23,12 @@ import io.gravitee.connector.http.endpoint.HttpClientOptions; import io.gravitee.connector.http.endpoint.HttpEndpoint; import io.gravitee.connector.http.stub.DummyHttpClientRequest; +import io.gravitee.gateway.api.ExecutionContext; import io.gravitee.gateway.api.http.HttpHeaderNames; import io.gravitee.gateway.api.http.HttpHeaders; import io.gravitee.gateway.api.proxy.ProxyRequest; +import io.gravitee.gateway.reactive.api.tracing.Tracer; +import io.gravitee.node.opentelemetry.tracer.noop.NoOpTracer; import io.vertx.core.Future; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientRequest; @@ -51,6 +54,9 @@ public class GrpcConnectionTest { private GrpcConnection cut; + @Mock + private ExecutionContext executionContext; + @Mock private HttpEndpoint endpoint; @@ -86,11 +92,21 @@ public void setUp() { httpClientRequest = spy(new DummyHttpClientRequest(options)); return Future.succeededFuture(httpClientRequest); }); + + when(executionContext.getTracer()).thenReturn(new Tracer(null, new NoOpTracer())); } @Test public void should_write_upstream_headers() { - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect( + executionContext, + client, + getAvailablePort(), + "host", + "/", + unused -> {}, + result -> new AtomicInteger(1).decrementAndGet() + ); cut.writeUpstreamHeaders(); @@ -102,7 +118,15 @@ public void should_write_upstream_headers() { @Test public void should_prevent_duplicated_headers() { - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect( + executionContext, + client, + getAvailablePort(), + "host", + "/", + unused -> {}, + result -> new AtomicInteger(1).decrementAndGet() + ); headers.add(HttpHeaderNames.CONTENT_TYPE, "application/grpc"); @@ -113,7 +137,15 @@ public void should_prevent_duplicated_headers() { @Test public void should_remove_host_header() { - cut.connect(client, getAvailablePort(), "host", "/", unused -> {}, result -> new AtomicInteger(1).decrementAndGet()); + cut.connect( + executionContext, + client, + getAvailablePort(), + "host", + "/", + unused -> {}, + result -> new AtomicInteger(1).decrementAndGet() + ); cut.writeUpstreamHeaders(); diff --git a/src/test/java/io/gravitee/connector/http/stub/ThrowingOnGoAwayHttpConnection.java b/src/test/java/io/gravitee/connector/http/stub/ThrowingOnGoAwayHttpConnection.java index 0191846f..175f5043 100644 --- a/src/test/java/io/gravitee/connector/http/stub/ThrowingOnGoAwayHttpConnection.java +++ b/src/test/java/io/gravitee/connector/http/stub/ThrowingOnGoAwayHttpConnection.java @@ -26,6 +26,7 @@ import io.vertx.core.net.SocketAddress; import java.security.cert.Certificate; import java.util.List; +import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.security.cert.X509Certificate; @@ -64,6 +65,11 @@ public Future shutdown(long timeoutMs) { return null; } + @Override + public Future shutdown(final long timeout, final TimeUnit unit) { + return null; + } + @Override public HttpConnection closeHandler(Handler handler) { return null;