diff --git a/junit/mockwebserver/pom.xml b/junit/mockwebserver/pom.xml index 1b598652e1d..b7cae35f49e 100644 --- a/junit/mockwebserver/pom.xml +++ b/junit/mockwebserver/pom.xml @@ -32,8 +32,8 @@ - com.squareup.okhttp3 - mockwebserver + io.vertx + vertx-web com.fasterxml.jackson.core diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/DefaultMockServer.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/DefaultMockServer.java index ff9c1ad7154..8a9cffbd428 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/DefaultMockServer.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/DefaultMockServer.java @@ -17,14 +17,12 @@ package io.fabric8.mockwebserver; import io.fabric8.mockwebserver.dsl.MockServerExpectation; +import io.fabric8.mockwebserver.http.Dispatcher; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.mockwebserver.internal.MockDispatcher; -import io.fabric8.mockwebserver.internal.MockSSLContextFactory; import io.fabric8.mockwebserver.internal.MockServerExpectationImpl; -import okhttp3.mockwebserver.Dispatcher; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; +import io.vertx.core.net.SelfSignedCertificate; -import java.io.IOException; import java.net.InetAddress; import java.net.Proxy; import java.util.HashMap; @@ -64,8 +62,9 @@ public DefaultMockServer(Context context, MockWebServer server, Map> responses, - Dispatcher dispatcher, boolean useHttps) { + public DefaultMockServer( + Context context, MockWebServer server, Map> responses, Dispatcher dispatcher, + boolean useHttps) { this.context = context; this.useHttps = useHttps; this.server = server; @@ -78,7 +77,7 @@ public DefaultMockServer(Context context, MockWebServer server, Map requestQueue; + private final AtomicInteger requestCount; + private final List listeners; + private Dispatcher dispatcher; + private ClientAuth clientAuth; + private final List enabledSecuredTransportProtocols; + private boolean ssl; + private SelfSignedCertificate selfSignedCertificate; + private HttpServer httpServer; + private int port; + private InetAddress inetAddress; + private List protocols; + private boolean started; + + public MockWebServer() { + vertx = Vertx.vertx(); + requestQueue = new LinkedBlockingQueue<>(); + requestCount = new AtomicInteger(); + listeners = new ArrayList<>(); + dispatcher = new QueueDispatcher(); + clientAuth = ClientAuth.NONE; + enabledSecuredTransportProtocols = new ArrayList<>(); + enabledSecuredTransportProtocols.addAll(DEFAULT_ENABLED_SECURE_TRANSPORT_PROTOCOLS); + protocols = Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1); + } + + private void before() { + if (started) { + return; + } + start(); + } + + public void start() { + start(NetServerOptions.DEFAULT_PORT); + } + + public void start(int port) { + start(InetAddress.getLoopbackAddress(), port); + } + + public synchronized void start(InetAddress inetAddress, int port) { + if (started) { + throw new IllegalStateException("start() already called"); + } + this.started = true; + this.inetAddress = inetAddress; + final HttpServerOptions options = new HttpServerOptions() + .setHost(inetAddress.getHostAddress()) + .setPort(port) + .setAlpnVersions(protocols.stream().map(Protocol::getHttpVersion).collect(Collectors.toList())) + .setWebSocketSubProtocols(Arrays.asList(SUPPORTED_WEBSOCKET_SUB_PROTOCOLS)); + if (ssl) { + selfSignedCertificate = SelfSignedCertificate.create(getHostName()); + options + .setSsl(true) + .setEnabledSecureTransportProtocols(new HashSet<>(enabledSecuredTransportProtocols)) + .setTrustOptions(selfSignedCertificate.trustOptions()) + .setKeyCertOptions(selfSignedCertificate.keyCertOptions()); + } + httpServer = vertx.createHttpServer(options); + httpServer.connectionHandler(event -> { + final RecordedHttpConnection connection = new RecordedHttpConnection( + event.remoteAddress(), event.localAddress(), ssl); + listeners.forEach(listener -> listener.onConnection(connection)); + event.closeHandler(res -> listeners.forEach(listener -> listener.onConnectionClosed(connection))); + }); + httpServer.requestHandler(new HttpServerRequestHandler(vertx) { + @Override + protected MockResponse onHttpRequest(RecordedRequest request) { + requestCount.incrementAndGet(); + requestQueue.add(request); + return dispatcher.dispatch(request); + } + }); + await(httpServer.listen(), "Unable to start MockWebServer"); + this.port = httpServer.actualPort(); + } + + public synchronized void shutdown() { + if (!started) { + return; + } + if (httpServer == null) { + throw new IllegalStateException("shutdown() before start()"); + } + dispatcher.shutdown(); + await(httpServer.close(), "Unable to close MockWebServer"); + } + + @Override + public void close() throws IOException { + shutdown(); + } + + public int getPort() { + before(); + return port; + } + + public String getHostName() { + before(); + return inetAddress.getCanonicalHostName(); + } + + public Proxy toProxyAddress() { + before(); + final InetSocketAddress address = new InetSocketAddress(getHostName(), getPort()); + return new Proxy(Proxy.Type.HTTP, address); + } + + public SelfSignedCertificate getSelfSignedCertificate() { + return selfSignedCertificate; + } + + public HttpUrl url(String path) { + if (path.startsWith("/")) { + path = path.substring(1); + } + final String schema = ssl ? "https" : "http"; + return HttpUrl.parse(schema + "://" + getHostName() + ":" + getPort() + "/" + path); + } + + public RecordedRequest takeRequest() throws InterruptedException { + return requestQueue.take(); + } + + public RecordedRequest takeRequest(long timeout, TimeUnit unit) throws InterruptedException { + return requestQueue.poll(timeout, unit); + } + + public int getRequestCount() { + return requestCount.get(); + } + + public void useHttps() { + this.ssl = true; + } + + public void enqueue(MockResponse response) { + if (dispatcher instanceof QueueDispatcher) { + ((QueueDispatcher) dispatcher).enqueueResponse(response); + } else { + throw new IllegalStateException("Dispatcher is not a QueueDispatcher"); + } + } + + public void addListener(MockWebServerListener listener) { + listeners.add(listener); + } + + public void setDispatcher(Dispatcher dispatcher) { + this.dispatcher = dispatcher; + } + + public void setProtocols(List protocols) { + this.protocols = protocols; + } + + private static T await(Future vertxFuture, String errorMessage) { + final CompletableFuture future = new CompletableFuture<>(); + vertxFuture.onComplete(r -> { + if (r.succeeded()) { + future.complete(r.result()); + } else { + future.completeExceptionally(r.cause()); + } + }); + try { + return future.get(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IllegalStateException(e); + } catch (ExecutionException | TimeoutException e) { + throw new IllegalStateException(errorMessage, e); + } + } +} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/MockWebServerListener.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/MockWebServerListener.java new file mode 100644 index 00000000000..4c14a973ae1 --- /dev/null +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/MockWebServerListener.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.mockwebserver; + +import io.fabric8.mockwebserver.http.RecordedHttpConnection; + +public interface MockWebServerListener { + default void onConnection(RecordedHttpConnection connection) { + } + + default void onConnectionClosed(RecordedHttpConnection connection) { + } +} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/ServerResponse.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/ServerResponse.java index 2b5e9cb34d4..9ae95693b90 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/ServerResponse.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/ServerResponse.java @@ -15,8 +15,8 @@ */ package io.fabric8.mockwebserver; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; public interface ServerResponse { diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/crud/CrudDispatcher.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/crud/CrudDispatcher.java index f1d059b6115..f88a2febae7 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/crud/CrudDispatcher.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/crud/CrudDispatcher.java @@ -18,10 +18,10 @@ import com.fasterxml.jackson.databind.JsonNode; import io.fabric8.mockwebserver.Context; import io.fabric8.mockwebserver.MockServerException; +import io.fabric8.mockwebserver.http.Dispatcher; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.zjsonpatch.JsonPatch; -import okhttp3.mockwebserver.Dispatcher; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.RecordedRequest; import java.net.HttpURLConnection; import java.util.ArrayList; @@ -32,12 +32,6 @@ public class CrudDispatcher extends Dispatcher { - private static final String POST = "POST"; - private static final String PUT = "PUT"; - private static final String PATCH = "PATCH"; - private static final String GET = "GET"; - private static final String DELETE = "DELETE"; - protected final Map map = Collections.synchronizedMap(new LinkedHashMap<>()); protected final Context context; @@ -53,7 +47,7 @@ public CrudDispatcher(Context context, AttributeExtractor attributeExtractor, Re @Override public MockResponse dispatch(RecordedRequest request) { String path = request.getPath(); - switch (request.getMethod().toUpperCase()) { + switch (request.method()) { case POST: return handleCreate(request); case PUT: diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/dsl/HttpMethod.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/dsl/HttpMethod.java index 817af73b793..c3037ac0859 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/dsl/HttpMethod.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/dsl/HttpMethod.java @@ -25,6 +25,17 @@ public enum HttpMethod { DELETE, OPTIONS, CONNECT, - ANY + ANY; + + public static HttpMethod fromVertx(io.vertx.core.http.HttpMethod method) { + if (method != null) { + for (HttpMethod m : HttpMethod.values()) { + if (m.toString().equalsIgnoreCase(method.toString())) { + return m; + } + } + } + return null; + } } diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/ChunkedResponse.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/ChunkedResponse.java index d5d6df848b8..539b5d57725 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/ChunkedResponse.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/ChunkedResponse.java @@ -16,11 +16,13 @@ package io.fabric8.mockwebserver.internal; import io.fabric8.mockwebserver.ServerResponse; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.mockwebserver.utils.ResponseProvider; import io.fabric8.mockwebserver.utils.ResponseProviders; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.RecordedRequest; +import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.List; import java.util.concurrent.TimeUnit; @@ -58,13 +60,13 @@ public ResponseProvider> getBodyProvider() { @Override public MockResponse toMockResponse(RecordedRequest request) { - MockResponse mockResponse = new MockResponse(); + final MockResponse mockResponse = new MockResponse(); mockResponse.setHeaders(bodyProvider.getHeaders()); - mockResponse.setChunkedBody(concatBody(request), DEFAULT_MAX_CHUNK_SIZE); + mockResponse.setChunkedBody(concatBody(request).getBytes(StandardCharsets.UTF_8), DEFAULT_MAX_CHUNK_SIZE); mockResponse.setResponseCode(bodyProvider.getStatusCode(request)); if (responseDelay > 0) { - mockResponse.setBodyDelay(responseDelay, responseDelayUnit); + mockResponse.setBodyDelay(Duration.ofMillis(responseDelayUnit.toMillis(responseDelay))); } return mockResponse; diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockDispatcher.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockDispatcher.java index 8aa6d41bb64..16c8d9f2b06 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockDispatcher.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockDispatcher.java @@ -18,10 +18,9 @@ import io.fabric8.mockwebserver.ServerRequest; import io.fabric8.mockwebserver.ServerResponse; -import io.fabric8.mockwebserver.dsl.HttpMethod; -import okhttp3.mockwebserver.Dispatcher; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.Dispatcher; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; import java.util.Collection; import java.util.Map; @@ -43,9 +42,8 @@ public MockResponse dispatch(RecordedRequest request) { webSocketSession.dispatch(request); } - HttpMethod method = HttpMethod.valueOf(request.getMethod()); String path = request.getPath(); - SimpleRequest key = new SimpleRequest(method, path); + SimpleRequest key = new SimpleRequest(request.method(), path); SimpleRequest keyForAnyMethod = new SimpleRequest(path); if (responses.containsKey(key)) { Queue queue = responses.get(key); diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockSSLContextFactory.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockSSLContextFactory.java deleted file mode 100644 index 3a3a1279ffc..00000000000 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockSSLContextFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fabric8.mockwebserver.internal; - -import io.fabric8.mockwebserver.MockServerException; -import io.fabric8.mockwebserver.utils.SSLUtils; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; - -public class MockSSLContextFactory { - - private MockSSLContextFactory() { - } - - public static SSLContext create() { - try { - KeyManager[] keyManagers = SSLUtils.keyManagers(MockSSLContextFactory.class.getResourceAsStream("/ssl/fabric8.crt"), - MockSSLContextFactory.class.getResourceAsStream("/ssl/fabric8-private-key.pem"), - "RSA", ""); - return SSLUtils.sslContext(keyManagers, null, true); - } catch (Exception e) { - throw new MockServerException("Exception creating SSLContext", e); - } - } -} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockServerExpectationImpl.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockServerExpectationImpl.java index 2e30817cf20..5a9e9828a80 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockServerExpectationImpl.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/MockServerExpectationImpl.java @@ -28,11 +28,11 @@ import io.fabric8.mockwebserver.dsl.ReturnOrWebsocketable; import io.fabric8.mockwebserver.dsl.TimesOnceableOrHttpHeaderable; import io.fabric8.mockwebserver.dsl.WebSocketSessionBuilder; +import io.fabric8.mockwebserver.http.Headers; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.mockwebserver.utils.BodyProvider; import io.fabric8.mockwebserver.utils.ResponseProvider; import io.fabric8.mockwebserver.utils.ResponseProviders; -import okhttp3.Headers; -import okhttp3.mockwebserver.RecordedRequest; import java.util.ArrayDeque; import java.util.ArrayList; diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/SimpleResponse.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/SimpleResponse.java index 9515d398a53..560ebcc9107 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/SimpleResponse.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/SimpleResponse.java @@ -17,11 +17,12 @@ package io.fabric8.mockwebserver.internal; import io.fabric8.mockwebserver.ServerResponse; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.mockwebserver.utils.ResponseProvider; import io.fabric8.mockwebserver.utils.ResponseProviders; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.RecordedRequest; +import java.time.Duration; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -64,7 +65,7 @@ public ResponseProvider getBodyProvider() { @Override public MockResponse toMockResponse(RecordedRequest request) { - MockResponse mockResponse = new MockResponse(); + final MockResponse mockResponse = new MockResponse(); mockResponse.setHeaders(bodyProvider.getHeaders()); mockResponse.setResponseCode(bodyProvider.getStatusCode(request)); @@ -72,18 +73,18 @@ public MockResponse toMockResponse(RecordedRequest request) { mockResponse.withWebSocketUpgrade(webSocketSession); // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism // see https://github.com/netty/netty/blob/4.1/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java#L366 - String requestWebsocketProtocol = request.getHeaders().get(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL); + String requestWebsocketProtocol = request.getHeader(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL); if (requestWebsocketProtocol != null // only add the response header if it's not set, to prevent changing custom response headers - && mockResponse.getHeaders().get(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL) == null) { + && mockResponse.header(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL) == null) { mockResponse.addHeader(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL, requestWebsocketProtocol); } } else { - mockResponse.setBody(bodyProvider.getBody(request)); + mockResponse.setBody(bodyProvider.getBody(request).getBytes()); } if (responseDelay > 0) { - mockResponse.setBodyDelay(responseDelay, responseDelayUnit); + mockResponse.setBodyDelay(Duration.ofMillis(responseDelayUnit.toMillis(responseDelay))); } return mockResponse; diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/WebSocketSession.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/WebSocketSession.java index ae399ced89f..11e9ba602a9 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/WebSocketSession.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/internal/WebSocketSession.java @@ -17,13 +17,12 @@ package io.fabric8.mockwebserver.internal; import io.fabric8.mockwebserver.MockServerException; -import io.fabric8.mockwebserver.dsl.HttpMethod; -import okhttp3.Response; -import okhttp3.WebSocket; -import okhttp3.WebSocketListener; -import okhttp3.mockwebserver.RecordedRequest; -import okio.ByteString; +import io.fabric8.mockwebserver.http.RecordedRequest; +import io.fabric8.mockwebserver.http.Response; +import io.fabric8.mockwebserver.http.WebSocket; +import io.fabric8.mockwebserver.http.WebSocketListener; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -58,11 +57,6 @@ public WebSocketSession(List open, WebSocketMessage failure, E this.executor = Executors.newScheduledThreadPool(1); } - @Override - public void onClosing(WebSocket webSocket, int code, String reason) { - webSocket.close(code, reason); - } - @Override public void onOpen(WebSocket webSocket, Response response) { activeSockets.add(webSocket); @@ -78,8 +72,8 @@ public void onOpen(WebSocket webSocket, Response response) { } @Override - public void onMessage(WebSocket webSocket, ByteString bytes) { - onMessage(webSocket, bytes.utf8()); + public void onMessage(WebSocket webSocket, byte[] bytes) { + onMessage(webSocket, new String(bytes, StandardCharsets.UTF_8)); } @Override @@ -93,6 +87,11 @@ public void onClosed(WebSocket webSocket, int code, String reason) { activeSockets.remove(webSocket); } + @Override + public void onClosing(WebSocket webSocket, int code, String reason) { + webSocket.close(code, reason); + } + private void send(WebSocket ws, Queue queue, String in) { if (queue != null && !queue.isEmpty()) { WebSocketMessage msg = queue.peek(); @@ -107,7 +106,7 @@ private void send(WebSocket ws, Queue queue, String in) { } private void checkIfShouldSendAgain(WebSocket ws, WebSocketMessage msg) { - String text = msg.isBinary() ? ByteString.of(msg.getBytes()).utf8() : msg.getBody(); + String text = msg.isBinary() ? new String(msg.getBytes(), StandardCharsets.UTF_8) : msg.getBody(); if (sentWebSocketMessagesRequestEvents.containsKey(text)) { Queue queue = sentWebSocketMessagesRequestEvents.get(text); send(ws, queue, text); @@ -115,9 +114,8 @@ private void checkIfShouldSendAgain(WebSocket ws, WebSocketMessage msg) { } public void dispatch(RecordedRequest request) { - HttpMethod method = HttpMethod.valueOf(request.getMethod()); - String path = request.getPath(); - SimpleRequest key = new SimpleRequest(method, path); + final String path = request.getPath(); + SimpleRequest key = new SimpleRequest(request.method(), path); SimpleRequest keyForAnyMethod = new SimpleRequest(path); if (httpRequestEvents.containsKey(key)) { Queue queue = httpRequestEvents.get(key); @@ -162,7 +160,7 @@ private void send(final WebSocket ws, final WebSocketMessage message) { executor.schedule(() -> { if (ws != null) { if (message.isBinary()) { - ws.send(ByteString.of(message.getBytes())); + ws.send(message.getBytes()); } else { ws.send(message.getBody()); } @@ -186,6 +184,7 @@ public void shutdown() { executor.shutdownNow(); } } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw MockServerException.launderThrowable(e); } } diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/BodyProvider.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/BodyProvider.java index 1379f535223..08e67fa88ee 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/BodyProvider.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/BodyProvider.java @@ -15,7 +15,7 @@ */ package io.fabric8.mockwebserver.utils; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.RecordedRequest; /** * A class that allows returning the body of a response given a certain request. diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/CertUtils.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/CertUtils.java deleted file mode 100644 index c8dde0df712..00000000000 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/CertUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.fabric8.mockwebserver.utils; - -import okio.ByteString; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.util.Base64; - -public class CertUtils { - - private CertUtils() { - } - - public static InputStream getInputStreamFromDataOrFile(String data, String file) throws FileNotFoundException { - if (data != null) { - final byte[] bytes; - ByteString decoded = ByteString.decodeBase64(data); - if (decoded != null) { - bytes = decoded.toByteArray(); - } else { - bytes = data.getBytes(); - } - - return new ByteArrayInputStream(bytes); - } - if (file != null) { - return new FileInputStream(file); - } - return null; - } - - public static KeyStore createKeyStore(InputStream certInputStream, InputStream keyInputStream, String clientKeyAlgo, - char[] clientKeyPassphrase) - throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException { - CertificateFactory certFactory = CertificateFactory.getInstance("X509"); - X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInputStream); - - byte[] keyBytes = decodeKey(keyInputStream); - - PrivateKey privateKey; - - KeyFactory keyFactory = KeyFactory.getInstance(clientKeyAlgo); - try { - // First let's try PKCS8 - privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes)); - } catch (InvalidKeySpecException e) { - // Otherwise try PKCS8 - RSAPrivateCrtKeySpec keySpec = PKCS1Util.decodePKCS1(keyBytes); - privateKey = keyFactory.generatePrivate(keySpec); - } - - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(null, clientKeyPassphrase); - - String alias = cert.getSubjectX500Principal().getName(); - keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, new Certificate[] { cert }); - - return keyStore; - } - - public static KeyStore createKeyStore(String clientCertData, String clientCertFile, String clientKeyData, - String clientKeyFile, String clientKeyAlgo, char[] clientKeyPassphrase) - throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException { - try (InputStream certInputStream = getInputStreamFromDataOrFile(clientCertData, clientCertFile); - InputStream keyInputStream = getInputStreamFromDataOrFile(clientKeyData, clientKeyFile)) { - return createKeyStore(certInputStream, keyInputStream, clientKeyAlgo, clientKeyPassphrase); - } - } - - private static byte[] decodeKey(InputStream keyInputStream) throws IOException { - try (BufferedReader keyReader = new BufferedReader(new InputStreamReader(keyInputStream)); - ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - String line; - while ((line = keyReader.readLine()) != null) { - baos.write(line.trim().getBytes()); - } - return Base64.getDecoder().decode(baos.toByteArray()); - } - } -} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/PKCS1Util.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/PKCS1Util.java deleted file mode 100644 index 31c1c82bcfa..00000000000 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/PKCS1Util.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.fabric8.mockwebserver.utils; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.spec.RSAPrivateCrtKeySpec; - -/** - * This code is inspired and taken over from net.auth.core:oauth - * (albeit in a highly stripped variation): - *

- * Source is from http://oauth.googlecode.com/svn/code/java/ which is licensed - * under the APL (http://oauth.googlecode.com/svn/code/java/LICENSE.txt) - *

- * All credits go to the original author (zhang) - * - * @author roland - * @since 30/09/15 - */ -class PKCS1Util { - - private PKCS1Util() { - } - - public static RSAPrivateCrtKeySpec decodePKCS1(byte[] keyBytes) throws IOException { - DerParser parser = new DerParser(keyBytes); - Asn1Object sequence = parser.read(); - sequence.validateSequence(); - parser = new DerParser(sequence.getValue()); - parser.read(); - - return new RSAPrivateCrtKeySpec(next(parser), next(parser), - next(parser), next(parser), - next(parser), next(parser), - next(parser), next(parser)); - } - - // ========================================================================================== - - private static BigInteger next(DerParser parser) throws IOException { - return parser.read().getInteger(); - } - - static class DerParser { - - private final InputStream in; - - DerParser(byte[] bytes) { - this.in = new ByteArrayInputStream(bytes); - } - - Asn1Object read() throws IOException { - int tag = in.read(); - - if (tag == -1) { - throw new IOException("Invalid DER: stream too short, missing tag"); - } - - int length = getLength(); - byte[] value = new byte[length]; - if (in.read(value) < length) { - throw new IOException("Invalid DER: stream too short, missing value"); - } - - return new Asn1Object(tag, value); - } - - private int getLength() throws IOException { - int i = in.read(); - if (i == -1) { - throw new IOException("Invalid DER: length missing"); - } - - if ((i & ~0x7F) == 0) { - return i; - } - - int num = i & 0x7F; - if (i >= 0xFF || num > 4) { - throw new IOException("Invalid DER: length field too big (" - + i + ")"); - } - - byte[] bytes = new byte[num]; - if (in.read(bytes) < num) { - throw new IOException("Invalid DER: length too short"); - } - - return new BigInteger(1, bytes).intValue(); - } - } - - static class Asn1Object { - - private final int type; - private final byte[] value; - private final int tag; - - public Asn1Object(int tag, byte[] value) { - this.tag = tag; - this.type = tag & 0x1F; - this.value = value; - } - - public byte[] getValue() { - return value; - } - - BigInteger getInteger() throws IOException { - if (type != 0x02) { - throw new IOException("Invalid DER: object is not integer"); //$NON-NLS-1$ - } - return new BigInteger(value); - } - - void validateSequence() throws IOException { - if (type != 0x10) { - throw new IOException("Invalid DER: not a sequence"); - } - if ((tag & 0x20) != 0x20) { - throw new IOException("Invalid DER: can't parse primitive entity"); - } - } - } -} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProvider.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProvider.java index 9e5ef4fa300..3735d342c36 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProvider.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProvider.java @@ -15,8 +15,8 @@ */ package io.fabric8.mockwebserver.utils; -import okhttp3.Headers; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.Headers; +import io.fabric8.mockwebserver.http.RecordedRequest; /** * A class that allows returning a response given a certain request. diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProviders.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProviders.java index 784176f6ba5..360eed59979 100644 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProviders.java +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/ResponseProviders.java @@ -15,8 +15,8 @@ */ package io.fabric8.mockwebserver.utils; -import okhttp3.Headers; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.Headers; +import io.fabric8.mockwebserver.http.RecordedRequest; import java.util.Arrays; import java.util.Collections; @@ -55,7 +55,7 @@ public static ResponseProvider> ofAll(int statusCode, R... elements) public static ResponseProvider of(final int statusCode, final BodyProvider bodyProvider) { if (bodyProvider != null) { return new ResponseProvider() { - private Headers headers = new Headers.Builder().build(); + private Headers headers = Headers.builder().build(); @Override public int getStatusCode(RecordedRequest request) { @@ -140,9 +140,9 @@ public int hashCode() { } private static Headers toHeaders(Map headers) { - final Headers.Builder builder = new Headers.Builder(); + final Headers.Builder builder = Headers.builder(); for (Map.Entry entry : headers.entrySet()) { - builder.set(entry.getKey(), entry.getValue()); + builder.setHeader(entry.getKey(), entry.getValue()); } return builder.build(); } diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/SSLUtils.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/SSLUtils.java deleted file mode 100644 index e63e016d8fc..00000000000 --- a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/utils/SSLUtils.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.fabric8.mockwebserver.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import static io.fabric8.mockwebserver.utils.CertUtils.createKeyStore; - -public final class SSLUtils { - - private SSLUtils() { - //Utility - } - - public static SSLContext sslContext(KeyManager[] keyManagers, TrustManager[] trustManagers, boolean trustCerts) - throws KeyManagementException, NoSuchAlgorithmException { - if (trustManagers == null && trustCerts) { - trustManagers = new TrustManager[] { new X509TrustManager() { - public void checkClientTrusted(X509Certificate[] chain, String s) { - } - - public void checkServerTrusted(X509Certificate[] chain, String s) { - } - - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - } }; - } - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagers, trustManagers, new SecureRandom()); - return sslContext; - } - - public static KeyManager[] keyManagers(InputStream certInputStream, InputStream keyInputStream, String algo, - String passphrase) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, - InvalidKeySpecException, IOException { - KeyStore keyStore = createKeyStore(certInputStream, keyInputStream, algo, passphrase.toCharArray()); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, passphrase.toCharArray()); - return kmf.getKeyManagers(); - } -} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/HttpServerRequestHandler.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/HttpServerRequestHandler.java new file mode 100644 index 00000000000..4e4274a235e --- /dev/null +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/HttpServerRequestHandler.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.mockwebserver.vertx; + +import io.fabric8.mockwebserver.dsl.HttpMethod; +import io.fabric8.mockwebserver.http.Headers; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; +import io.vertx.core.Future; +import io.vertx.core.Handler; +import io.vertx.core.Vertx; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.HttpServerRequest; +import io.vertx.core.http.HttpServerResponse; + +public abstract class HttpServerRequestHandler implements Handler { + + private static final String CONTENT_LENGTH = "Content-Length"; + private static final String CONTENT_TYPE = "Content-Type"; + + private final Vertx vertx; + + protected HttpServerRequestHandler(Vertx vertx) { + this.vertx = vertx; + } + + protected abstract MockResponse onHttpRequest(RecordedRequest request); + + @Override + public final void handle(HttpServerRequest event) { + final Handler exceptionHandler = err -> event.response().setStatusCode(500).setStatusMessage(err.getMessage()) + .send(); + event.resume(); + final Future body; + if (event.headers().contains(CONTENT_LENGTH) || event.headers().contains(CONTENT_TYPE)) { + body = event.body(); + } else { + body = Future.succeededFuture(null); + } + body.onFailure(exceptionHandler); + body.onSuccess(bodyBuffer -> { + final RecordedRequest request = new RecordedRequest( + HttpMethod.fromVertx(event.method()), + event.uri(), + Headers.builder().addAll(event.headers()).build(), + new io.fabric8.mockwebserver.http.Buffer(bodyBuffer == null ? null : bodyBuffer.getBytes())); + final MockResponse mockResponse = onHttpRequest(request); + // WebSocket + if (mockResponse.getWebSocketListener() != null) { + event.toWebSocket() + .onFailure(exceptionHandler) + .onSuccess(new ServerWebSocketHandler(request, mockResponse)); + return; + } + // Standard Http Response + final HttpServerResponse vertxResponse = event.response(); + vertxResponse.setStatusCode(mockResponse.code()); + mockResponse.headers().toMultimap().forEach((key, values) -> vertxResponse.headers().add(key, values)); + if (mockResponse.getBody() != null && mockResponse.getBody().size() > 0) { + vertxResponse.headers().add(CONTENT_LENGTH, String.valueOf(mockResponse.getBody().size())); + final io.vertx.core.buffer.Buffer toSend = io.vertx.core.buffer.Buffer.buffer(mockResponse.getBody().getBytes()); + if (mockResponse.getBodyDelay() != null) { + vertx.setTimer(mockResponse.getBodyDelay().toMillis(), timerId -> vertxResponse.send(toSend)); + } else { + vertxResponse.send(toSend); + } + } else { + vertxResponse.end(); + } + }); + + } +} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/Protocol.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/Protocol.java new file mode 100644 index 00000000000..e34b452a8f2 --- /dev/null +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/Protocol.java @@ -0,0 +1,38 @@ +package io.fabric8.mockwebserver.vertx; + +import io.vertx.core.http.HttpVersion; + +/** + * Compatibility layer for OkHttp. + */ +public enum Protocol { + HTTP_1_0("http/1.0", HttpVersion.HTTP_1_0), + HTTP_1_1("http/1.1", HttpVersion.HTTP_1_1), + HTTP_2("h2", HttpVersion.HTTP_2); + + private final String protocolName; + private final HttpVersion httpVersion; + + Protocol(String protocolName, HttpVersion httpVersion) { + this.protocolName = protocolName; + this.httpVersion = httpVersion; + } + + public static Protocol get(String protocol) { + for (Protocol p : Protocol.values()) { + if (p.protocolName.equals(protocol)) { + return p; + } + } + throw new IllegalArgumentException("Unknown protocol: " + protocol); + } + + public HttpVersion getHttpVersion() { + return httpVersion; + } + + @Override + public String toString() { + return protocolName; + } +} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/ServerWebSocketHandler.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/ServerWebSocketHandler.java new file mode 100644 index 00000000000..6b51d9298fd --- /dev/null +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/ServerWebSocketHandler.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.mockwebserver.vertx; + +import io.fabric8.mockwebserver.http.RecordedRequest; +import io.fabric8.mockwebserver.http.Response; +import io.fabric8.mockwebserver.http.WebSocketListener; +import io.vertx.core.Handler; +import io.vertx.core.http.ServerWebSocket; + +public class ServerWebSocketHandler implements Handler { + + private static final int WEBSOCKET_CLOSE_CODE_SERVER_ERROR = 1011; + + private final RecordedRequest request; + private final Response response; + + public ServerWebSocketHandler(RecordedRequest request, Response response) { + this.request = request; + this.response = response; + } + + @Override + public void handle(ServerWebSocket serverWebSocket) { + final WebSocketListener wsListener = response.getWebSocketListener(); + final VertxMockWebSocket mockWebSocket = new VertxMockWebSocket(request, serverWebSocket); + serverWebSocket.textMessageHandler(text -> wsListener.onMessage(mockWebSocket, text)); + serverWebSocket.binaryMessageHandler(buff -> wsListener.onMessage(mockWebSocket, buff.getBytes())); + serverWebSocket.frameHandler(frame -> { + if (frame.isClose()) { + wsListener.onClosing(mockWebSocket, frame.closeStatusCode(), frame.closeReason()); + } + serverWebSocket.fetch(1); + }); + // use end, not close, because close is processed immediately vs. end is in frame order + serverWebSocket.endHandler(v -> wsListener.onClosed( + mockWebSocket, + serverWebSocket.closeStatusCode() == null ? WEBSOCKET_CLOSE_CODE_SERVER_ERROR + : serverWebSocket.closeStatusCode(), + serverWebSocket.closeReason())); + serverWebSocket.exceptionHandler(err -> wsListener.onFailure(mockWebSocket, err, response)); + serverWebSocket.accept(); + wsListener.onOpen(mockWebSocket, response); + serverWebSocket.fetch(1); + } +} diff --git a/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/VertxMockWebSocket.java b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/VertxMockWebSocket.java new file mode 100644 index 00000000000..2efe5117615 --- /dev/null +++ b/junit/mockwebserver/src/main/java/io/fabric8/mockwebserver/vertx/VertxMockWebSocket.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.mockwebserver.vertx; + +import io.fabric8.mockwebserver.http.RecordedRequest; +import io.fabric8.mockwebserver.http.WebSocket; +import io.vertx.core.Future; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.ServerWebSocket; + +public class VertxMockWebSocket implements WebSocket { + private final RecordedRequest request; + private final ServerWebSocket webSocket; + + public VertxMockWebSocket(RecordedRequest request, ServerWebSocket webSocket) { + this.request = request; + this.webSocket = webSocket; + } + + @Override + public RecordedRequest request() { + return request; + } + + @Override + public boolean send(String text) { + final Future send = webSocket.writeTextMessage(text); + if (send.isComplete()) { + return send.succeeded(); + } + return true; + } + + @Override + public boolean send(byte[] bytes) { + final Future send = webSocket.writeBinaryMessage(Buffer.buffer(bytes)); + if (send.isComplete()) { + return send.succeeded(); + } + return true; + } + + @Override + public boolean close(int code, String reason) { + final Future close = webSocket.close((short) code, reason); + if (close.isComplete()) { + return close.succeeded(); + } + return true; + } +} diff --git a/junit/mockwebserver/src/main/resources/ssl/fabric8-private-key.pem b/junit/mockwebserver/src/main/resources/ssl/fabric8-private-key.pem deleted file mode 100644 index b6bb69d0c55..00000000000 --- a/junit/mockwebserver/src/main/resources/ssl/fabric8-private-key.pem +++ /dev/null @@ -1,50 +0,0 @@ -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 -Sqju3/8JhKlPzgcIeEtTEncKaJh9UA== diff --git a/junit/mockwebserver/src/main/resources/ssl/fabric8.crt b/junit/mockwebserver/src/main/resources/ssl/fabric8.crt deleted file mode 100644 index 5b01aa30127..00000000000 --- a/junit/mockwebserver/src/main/resources/ssl/fabric8.crt +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFPzCCAycCFFa1f+dP0SR0nMoPfO+MrMRNfjHaMA0GCSqGSIb3DQEBCwUAMFwx -CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRUwEwYDVQQHDAxEZWZh -dWx0IENpdHkxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0y -MTExMDMwODU0NTRaFw0zMTExMDEwODU0NTRaMFwxCzAJBgNVBAYTAkFVMRMwEQYD -VQQIDApTb21lLVN0YXRlMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAN5Y08LhIkTwMpcZTkkhKytjWecjbj2+Y7rH6kR+VwYGppF5B6FF -Q14wUaN73aNmT7TGHw1s0V/g5+zAmdJccC6k4joIURFLZrKbgi4Zfbhzta+gx4fQ -jz/DxMlMQo2ZYJx25pnHnPTjWB2RAdAp61gmTNWGHmna1sixiUEt79cYfcjMBVt4 -V3oZQMrfYTIU2tJI60wQ7Bt6OYfbAnKwsXEawkXJJue/IR2MO9N0ak12o9EJT3cr -8F9GjXJypJmJI5sCHrTkN2jcMxCUTSuTSKbgFBfHC9pW6FvOzNHxciWfz9BPkfKy -INjlHaGBCrXIm1e1svvIUZBJ417UIb0ZvUk2ccJ0CR/6f1EVWiKyOyfwwZxILGlO -zQbXo6JrjWdBoosHKqHj75qK2GFRx33q6Nichx6WMzJymQvRUxfNnvHAcdT5oc9G -RFCwPNt/THRvszBAPleQTWtg/PD9PAnqqGk+jHOVD8fmGoSX3N0+lnJAtx+vliW5 -pENJMBpHVCu6qVYzZnPLmIG2G/HuGtg1D9F7mlun5vgzuHUjrO+iGsyIJu28xCtZ -hlYa04c+xb61RdNDJva8hggYhkywtnM6KNefvz/QgDTvG6K+qVD+OYLqM1kBkILk -9Gyz0pAtYla71XeMRwrl0Ky0m/l6hxnpFbLxKGgvZ+6mnaNgJGi1rzyZAgMBAAEw -DQYJKoZIhvcNAQELBQADggIBAJ1tNTAnPgAbfhXVxtVnnNPFGsrmUgtBj0f8NsY3 -F0ODX50TIjbVLYp7j3u+dgZu9/ruTOHcGLywNi5mJWB+s27KJJn3nBFPmd9d/QIV -zmjn5IVvikXezEjECQOscwDhwpSbzHqLoieDTJntVUyaNctAZM1YOxVKO97pCDdw -tV74xDzdnI/4JQFQPfshD699r3dtU5ax/jiVCvqM5hTAJ2M/UVyQtxm3lKzMYLNu -77chlVf8/hTop9B6Q4tD6Ajj2KPxaHB7y+5lhci5Rvb2YLVDs0HLq8UJmoJW3FLw -slrjs0NerSWoz5JfhmOQ0N9E3NBdV/kGr27WUeSlNOYh5bqneDCX+hPrO/4NtvpG -WnnJX9W6S6e5GBFsNwQIB9SQCjj9zKWqgszS937HRd9gLmnOCPm7jbCO5uOjDo5q -0t+E20r9xv+4il1QV7tkGg13texGDR43aGzsSNQ66PXOwzeeCPkFzrSu1QFBh7LL -69VMJIbgm3ywYJjO0vIi0mW+kAiqcniIxbDTcCuEI0yuVLyRNaAe6kWWLMVaJLUw -V4TNAOT7x8ZYGQGjhz2DAImvXMwZTK2wRwyv8S11G+ebIIUb4EXGbMksjU6tTquq -ViHO3TGAKPTHIjCYdNT/ZGYQ/PHXLmaDGSOcoW8FPT9ROPxXRSNicNfzLJk/o4Im -AZC5 ------END CERTIFICATE----- diff --git a/junit/mockwebserver/src/main/resources/ssl/fabric8.csr b/junit/mockwebserver/src/main/resources/ssl/fabric8.csr deleted file mode 100644 index ef0eea5121d..00000000000 --- a/junit/mockwebserver/src/main/resources/ssl/fabric8.csr +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIEoTCCAokCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx -FTATBgNVBAcMDERlZmF1bHQgQ2l0eTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3ljTwuEi -RPAylxlOSSErK2NZ5yNuPb5jusfqRH5XBgamkXkHoUVDXjBRo3vdo2ZPtMYfDWzR -X+Dn7MCZ0lxwLqTiOghREUtmspuCLhl9uHO1r6DHh9CPP8PEyUxCjZlgnHbmmcec -9ONYHZEB0CnrWCZM1YYeadrWyLGJQS3v1xh9yMwFW3hXehlAyt9hMhTa0kjrTBDs -G3o5h9sCcrCxcRrCRckm578hHYw703RqTXaj0QlPdyvwX0aNcnKkmYkjmwIetOQ3 -aNwzEJRNK5NIpuAUF8cL2lboW87M0fFyJZ/P0E+R8rIg2OUdoYEKtcibV7Wy+8hR -kEnjXtQhvRm9STZxwnQJH/p/URVaIrI7J/DBnEgsaU7NBtejomuNZ0GiiwcqoePv -morYYVHHfero2JyHHpYzMnKZC9FTF82e8cBx1Pmhz0ZEULA8239MdG+zMEA+V5BN -a2D88P08CeqoaT6Mc5UPx+YahJfc3T6WckC3H6+WJbmkQ0kwGkdUK7qpVjNmc8uY -gbYb8e4a2DUP0XuaW6fm+DO4dSOs76IazIgm7bzEK1mGVhrThz7FvrVF00Mm9ryG -CBiGTLC2czoo15+/P9CANO8bor6pUP45guozWQGQguT0bLPSkC1iVrvVd4xHCuXQ -rLSb+XqHGekVsvEoaC9n7qado2AkaLWvPJkCAwEAAaAAMA0GCSqGSIb3DQEBCwUA -A4ICAQCExP0WiJbGkhbpIRVN30seLat5upU3WauQy4fGeDKZAq37LguhzeHkWXtu -Rifb5fz8e7PTOz1fwjHJ8pBQsy5mRoMDXYdtyn6S6A2xGTPUYT82mN6BSJbwJDQm -Y4l4Lhg+7cEvqls+Mx9Dq0eSlM7hH7ezOl5c25U+lG74dHLT2gq5ornjdBk2JKnx -2c95646UomKJKVZtzfPLFRJhmVOr2ndkzooF1GlWXZsU57hflH0Y6argAqC+Y/Hu -AFqsm48Uwixex1FfX53aEFnZG1vkDYm48idGUDEa1QNqqC7Wt0qDM8iZtYaHoc9D -wOSD4KGOUOvzooqKmRzHRRRXfL/K3xzFOFAbxJf5YbVHmRGHEWbEXwnjhz1PHgmS -sXNtmVSt7/ycGKRUHyK4s2xIol45EaD7B+80st0fj0n5WGnpX0Wx/XxIepoD7/dG -H3HNjJD9UyGW3l2q6TojQrYLdTo+k9/CS6yMbbI++QyPlv/cnI1JpS/9+wvF8RrX -1AfWplKt+T8gOs64Ns7triUGD96IAqZfj46olQBN90BwCZ1BasneZyDYhClRCrfN -0znZT0cwgCs0q+UU+WmMcfBWO7ctKj3cz3+SmX+R16nTFi5Uuj3J9ED0V1o687jZ -YgtA3vz5F9lf9DaKJ/23GuA2X7HYWCUDiLtB2junYNJ0toJNJw== ------END CERTIFICATE REQUEST----- diff --git a/junit/mockwebserver/src/main/resources/ssl/fabric8.pub b/junit/mockwebserver/src/main/resources/ssl/fabric8.pub deleted file mode 100644 index ba5c2260a5e..00000000000 --- a/junit/mockwebserver/src/main/resources/ssl/fabric8.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDeWNPC4SJE8DKXGU5JISsrY1nnI249vmO6x+pEflcGBqaReQehRUNeMFGje92jZk+0xh8NbNFf4OfswJnSXHAupOI6CFERS2aym4IuGX24c7WvoMeH0I8/w8TJTEKNmWCcduaZx5z041gdkQHQKetYJkzVhh5p2tbIsYlBLe/XGH3IzAVbeFd6GUDK32EyFNrSSOtMEOwbejmH2wJysLFxGsJFySbnvyEdjDvTdGpNdqPRCU93K/BfRo1ycqSZiSObAh605Ddo3DMQlE0rk0im4BQXxwvaVuhbzszR8XIln8/QT5HysiDY5R2hgQq1yJtXtbL7yFGQSeNe1CG9Gb1JNnHCdAkf+n9RFVoisjsn8MGcSCxpTs0G16Oia41nQaKLByqh4++aithhUcd96ujYnIceljMycpkL0VMXzZ7xwHHU+aHPRkRQsDzbf0x0b7MwQD5XkE1rYPzw/TwJ6qhpPoxzlQ/H5hqEl9zdPpZyQLcfr5YluaRDSTAaR1QruqlWM2Zzy5iBthvx7hrYNQ/Re5pbp+b4M7h1I6zvohrMiCbtvMQrWYZWGtOHPsW+tUXTQyb2vIYIGIZMsLZzOijXn78/0IA07xuivqlQ/jmC6jNZAZCC5PRss9KQLWJWu9V3jEcK5dCstJv5eocZ6RWy8ShoL2fupp2jYCRota88mQ== diff --git a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerCrudTest.groovy b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerCrudTest.groovy index 2cc28a99290..35cb6b88898 100644 --- a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerCrudTest.groovy +++ b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerCrudTest.groovy @@ -19,7 +19,6 @@ import io.fabric8.mockwebserver.crud.CrudDispatcher import io.vertx.core.Future import io.vertx.core.Vertx import io.vertx.ext.web.client.WebClient -import okhttp3.mockwebserver.MockWebServer import spock.lang.Shared import spock.lang.Specification import spock.util.concurrent.AsyncConditions diff --git a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerHttpsTest.groovy b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerHttpsTest.groovy index 35cb5ff0a4e..ff6eba19294 100644 --- a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerHttpsTest.groovy +++ b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerHttpsTest.groovy @@ -15,24 +15,39 @@ */ package io.fabric8.mockwebserver -import okhttp3.OkHttpClient +import io.vertx.core.Vertx +import io.vertx.ext.web.client.WebClient +import io.vertx.ext.web.client.WebClientOptions import spock.lang.Shared import spock.lang.Specification +import spock.util.concurrent.AsyncConditions class DefaultMockServerHttpsTest extends Specification { + @Shared + static def vertx = Vertx.vertx() + DefaultMockServer server - @Shared - OkHttpClient client = new OkHttpClient() + WebClient client def setup() { server = new DefaultMockServer(true) server.start() + client = WebClient.create(vertx, new WebClientOptions() + .setSsl(true) + .setTrustOptions(server.getSelfSignedCertificate().trustOptions()) + .setKeyCertOptions(server.getSelfSignedCertificate().keyCertOptions())) + } def cleanup() { server.shutdown() + client.close() + } + + def cleanupSpec() { + vertx.close() } def "url, with path, returns URL with HTTPS protocol"() { @@ -42,4 +57,24 @@ class DefaultMockServerHttpsTest extends Specification { then: assert result.startsWith("https://") } + + + def "GET /, with empty store, should return 404"() { + given: "An HTTP request to /" + def request = client.get(server.port, server.getHostName(), "/").ssl(true) + and: "An instance of AsyncConditions" + def async = new AsyncConditions(2) + + when: "The request is sent and completed" + request.send().onComplete { res -> + if (res.failed()) { + res.cause().printStackTrace() + } + async.evaluate { assert res.result().statusCode() == 404 } + async.evaluate { assert res.result().body() == null} + } + + then: "Expect the result to be completed in the specified time" + async.await(10) + } } diff --git a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerTest.groovy b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerTest.groovy index 85a6d9ca769..c888277b6ee 100644 --- a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerTest.groovy +++ b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/DefaultMockServerTest.groovy @@ -15,14 +15,14 @@ */ package io.fabric8.mockwebserver +import io.fabric8.mockwebserver.http.Headers +import io.fabric8.mockwebserver.http.RecordedRequest import io.fabric8.mockwebserver.internal.WebSocketMessage import io.fabric8.mockwebserver.utils.ResponseProvider import io.vertx.core.Future import io.vertx.core.Vertx import io.vertx.core.http.WebSocketClient import io.vertx.ext.web.client.WebClient -import okhttp3.Headers -import okhttp3.mockwebserver.RecordedRequest import spock.lang.Specification import spock.util.concurrent.AsyncConditions diff --git a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/crud/CrudDispatcherTest.groovy b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/crud/CrudDispatcherTest.groovy index 5557b094cf2..e018ef5f87b 100644 --- a/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/crud/CrudDispatcherTest.groovy +++ b/junit/mockwebserver/src/test/groovy/io/fabric8/mockwebserver/crud/CrudDispatcherTest.groovy @@ -17,12 +17,12 @@ package io.fabric8.mockwebserver.crud import io.fabric8.mockwebserver.Context import io.fabric8.mockwebserver.DefaultMockServer +import io.fabric8.mockwebserver.MockWebServer import io.fabric8.mockwebserver.ServerRequest import io.fabric8.mockwebserver.ServerResponse import io.vertx.core.Vertx import io.vertx.core.buffer.Buffer import io.vertx.ext.web.client.WebClient -import okhttp3.mockwebserver.MockWebServer import spock.lang.Shared import spock.lang.Specification import spock.util.concurrent.AsyncConditions diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpClientProxyTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpClientProxyTest.java index b1a636ef01d..06e170da5a5 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpClientProxyTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpClientProxyTest.java @@ -16,15 +16,13 @@ package io.fabric8.kubernetes.client.http; import io.fabric8.mockwebserver.DefaultMockServer; -import okhttp3.Headers; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.RecordedRequest; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.net.InetSocketAddress; -import java.util.Collections; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; @@ -61,9 +59,8 @@ protected void proxyConfigurationAddsRequiredHeaders() throws Exception { // Then assertThat(server.getLastRequest()) .extracting(RecordedRequest::getHeaders) - .extracting(Headers::toMultimap) - .hasFieldOrPropertyWithValue("Host", Collections.singletonList("0.0.0.0:" + server.getPort())) - .hasFieldOrPropertyWithValue("Proxy-Authorization", Collections.singletonList("auth:cred")); + .returns("0.0.0.0:" + server.getPort(), h -> h.header("Host")) + .returns("auth:cred", h -> h.header("Proxy-Authorization")); } } } diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpLoggingInterceptorTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpLoggingInterceptorTest.java index 0e3a86f62b0..f4646c42d00 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpLoggingInterceptorTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpLoggingInterceptorTest.java @@ -17,14 +17,14 @@ import io.fabric8.mockwebserver.Context; import io.fabric8.mockwebserver.DefaultMockServer; +import io.fabric8.mockwebserver.MockWebServer; import io.fabric8.mockwebserver.ServerRequest; import io.fabric8.mockwebserver.ServerResponse; +import io.fabric8.mockwebserver.http.Buffer; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedRequest; import io.fabric8.mockwebserver.internal.SimpleRequest; import io.fabric8.mockwebserver.utils.ResponseProviders; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import okio.Buffer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPostTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPostTest.java index 51aa847f774..f1ba2be7eda 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPostTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPostTest.java @@ -16,7 +16,7 @@ package io.fabric8.kubernetes.client.http; import io.fabric8.mockwebserver.DefaultMockServer; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.RecordedRequest; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPutTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPutTest.java index a56e417fd13..21184bd36de 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPutTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractHttpPutTest.java @@ -16,7 +16,7 @@ package io.fabric8.kubernetes.client.http; import io.fabric8.mockwebserver.DefaultMockServer; -import okhttp3.mockwebserver.RecordedRequest; +import io.fabric8.mockwebserver.http.RecordedRequest; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractSimultaneousConnectionsTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractSimultaneousConnectionsTest.java index 0c6914bbcb4..dfa940bed65 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractSimultaneousConnectionsTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/AbstractSimultaneousConnectionsTest.java @@ -18,11 +18,13 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import okhttp3.Protocol; -import okhttp3.Response; -import okhttp3.WebSocketListener; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; +import io.fabric8.mockwebserver.MockWebServer; +import io.fabric8.mockwebserver.MockWebServerListener; +import io.fabric8.mockwebserver.http.MockResponse; +import io.fabric8.mockwebserver.http.RecordedHttpConnection; +import io.fabric8.mockwebserver.http.Response; +import io.fabric8.mockwebserver.http.WebSocketListener; +import io.fabric8.mockwebserver.vertx.Protocol; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -30,17 +32,11 @@ import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; -import java.io.Closeable; import java.io.IOException; -import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; import java.net.URI; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -51,8 +47,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -import javax.net.ServerSocketFactory; - import static org.assertj.core.api.Assertions.assertThat; public abstract class AbstractSimultaneousConnectionsTest { @@ -63,7 +57,7 @@ public abstract class AbstractSimultaneousConnectionsTest { private static final int MAX_HTTP_1_CONNECTIONS = 2048; // Should be able to at least make 2048 private static final int MAX_HTTP_1_WS_CONNECTIONS = 1024; // Should be able to at least make 1024 - private RegisteredServerSocketFactory serverSocketFactory; + private RegisteredConnections registeredConnections; private MockWebServer mockWebServer; private ExecutorService httpExecutor; private HttpServer httpServer; @@ -72,9 +66,9 @@ public abstract class AbstractSimultaneousConnectionsTest { @BeforeEach void prepareServerAndBuilder() throws IOException { - serverSocketFactory = new RegisteredServerSocketFactory(); + registeredConnections = new RegisteredConnections(); mockWebServer = new MockWebServer(); - mockWebServer.setServerSocketFactory(serverSocketFactory); + mockWebServer.addListener(registeredConnections); httpExecutor = Executors.newCachedThreadPool(); httpServer = HttpServer.create(new InetSocketAddress(0), 0); httpServer.setExecutor(httpExecutor); @@ -84,8 +78,7 @@ void prepareServerAndBuilder() throws IOException { } @AfterEach - void stopServer() throws IOException { - serverSocketFactory.close(); + void stopServer() { mockWebServer.shutdown(); httpServer.stop(0); httpExecutor.shutdownNow(); @@ -93,7 +86,7 @@ void stopServer() throws IOException { protected abstract HttpClient.Factory getHttpClientFactory(); - private void withHttp1() throws IOException { + private void withHttp1() { mockWebServer.setProtocols(Collections.singletonList(Protocol.HTTP_1_1)); mockWebServer.start(); } @@ -146,14 +139,14 @@ public void http1WebSocketConnectionsBeforeUpgrade() throws Exception { @DisabledOnOs(OS.WINDOWS) public void http1WebSocketConnections() throws Exception { withHttp1(); - final Collection serverSockets = ConcurrentHashMap.newKeySet(); + final Collection serverSockets = ConcurrentHashMap.newKeySet(); final Collection clientSockets = ConcurrentHashMap.newKeySet(); final CyclicBarrier cyclicBarrier = new CyclicBarrier(2); final CountDownLatch latch = new CountDownLatch(MAX_HTTP_1_WS_CONNECTIONS); final MockResponse response = new MockResponse() .withWebSocketUpgrade(new WebSocketListener() { @Override - public void onOpen(okhttp3.WebSocket webSocket, Response response) { + public void onOpen(io.fabric8.mockwebserver.http.WebSocket webSocket, Response response) { try { cyclicBarrier.await(1, TimeUnit.SECONDS); } catch (Exception ignore) { @@ -181,11 +174,11 @@ public void onMessage(WebSocket webSocket, String text) { assertThat(latch.await(60L, TimeUnit.SECONDS)).isTrue(); assertThat(serverSockets.size()) .isEqualTo(MAX_HTTP_1_WS_CONNECTIONS) - .isLessThanOrEqualTo((int) serverSocketFactory.activeConnections()); + .isLessThanOrEqualTo(registeredConnections.activeConnections()); // assertThat(clientSockets) // .hasSize(MAX_HTTP_1_WS_CONNECTIONS); } finally { - for (okhttp3.WebSocket socket : serverSockets) { + for (io.fabric8.mockwebserver.http.WebSocket socket : serverSockets) { socket.close(1000, "done"); } } @@ -237,50 +230,23 @@ public final void await() { } } - private static class RegisteredServerSocketFactory extends ServerSocketFactory implements Closeable { - - private final Set connections = new HashSet<>(); + private static class RegisteredConnections implements MockWebServerListener { - final long activeConnections() { - return connections.stream().filter(Socket::isConnected).filter(s -> !s.isClosed()).count(); - } + private final Set connections = ConcurrentHashMap.newKeySet(); - @Override - public final void close() { - for (Socket socket : connections) { - try { - socket.close(); - } catch (IOException ignored) { - // ignored - } - } - } - - @Override - public ServerSocket createServerSocket() throws IOException { - return new ServerSocket() { - @Override - public Socket accept() throws IOException { - final Socket socket = super.accept(); - connections.add(socket); - return socket; - } - }; - } - - @Override - public ServerSocket createServerSocket(int port) throws IOException { - throw new SocketException("not implemented"); + final int activeConnections() { + return connections.size(); } @Override - public ServerSocket createServerSocket(int port, int backlog) throws IOException { - throw new SocketException("not implemented"); + public void onConnection(RecordedHttpConnection connection) { + connections.add(connection); + MockWebServerListener.super.onConnection(connection); } @Override - public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException { - throw new SocketException("not implemented"); + public void onConnectionClosed(RecordedHttpConnection connection) { + connections.remove(connection); } } }