This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-kafka-connector.git
commit ad2d9e643e3fd265aae215e774ce20f1fedcba62 Author: Tadayoshi Sato <[email protected]> AuthorDate: Thu Mar 11 22:11:45 2021 +0900 Introduce MockWebServer extension for testing #1085 --- tests/itests-common/pom.xml | 10 +- .../common/services/mockweb/MockWebService.java | 136 +++++++++++++++++++++ .../https/sink/CamelSinkHTTPSITCase.java | 52 ++------ .../nettyhttp/sink/CamelSinkNettyhttpITCase.java | 19 ++- 4 files changed, 163 insertions(+), 54 deletions(-) diff --git a/tests/itests-common/pom.xml b/tests/itests-common/pom.xml index d4ef893..349e49b 100644 --- a/tests/itests-common/pom.xml +++ b/tests/itests-common/pom.xml @@ -28,6 +28,14 @@ <artifactId>itests-common</artifactId> <name>Camel-Kafka-Connector :: Tests :: Common</name> + <dependencies> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>mockwebserver</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <build> <plugins> <plugin> @@ -45,4 +53,4 @@ </plugins> </build> -</project> \ No newline at end of file +</project> diff --git a/tests/itests-common/src/test/java/org/apache/camel/kafkaconnector/common/services/mockweb/MockWebService.java b/tests/itests-common/src/test/java/org/apache/camel/kafkaconnector/common/services/mockweb/MockWebService.java new file mode 100644 index 0000000..23d3044 --- /dev/null +++ b/tests/itests-common/src/test/java/org/apache/camel/kafkaconnector/common/services/mockweb/MockWebService.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.kafkaconnector.common.services.mockweb; + +import java.security.KeyStore; +import java.util.stream.IntStream; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MockWebService implements BeforeEachCallback, AfterEachCallback { + private static final Logger LOG = LoggerFactory.getLogger(MockWebService.class); + + private boolean useHttps; + private String keystore; + private String keystorePassword; + private String truststore; + private String truststorePassword; + + private MockWebServer server; + + @Override + public void beforeEach(ExtensionContext extensionContext) throws Exception { + LOG.debug("Starting MockWebServer..."); + server = new MockWebServer(); + if (useHttps) { + KeyManagerFactory kmFactory = null; + if (keystore != null) { + KeyStore keyStore = KeyStore.getInstance("JKS"); + String password = keystorePassword == null ? "" : keystorePassword; + keyStore.load(getClass().getResourceAsStream(keystore), password.toCharArray()); + kmFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmFactory.init(keyStore, password.toCharArray()); + } + TrustManagerFactory tmFactory = null; + if (truststore != null) { + KeyStore trustStore = KeyStore.getInstance("JKS"); + String password = truststorePassword == null ? "" : truststorePassword; + trustStore.load(getClass().getResourceAsStream(truststore), password.toCharArray()); + tmFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + tmFactory.init(trustStore); + } + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init( + kmFactory == null ? null : kmFactory.getKeyManagers(), + tmFactory == null ? null : tmFactory.getTrustManagers(), + null); + server.useHttps(sslContext.getSocketFactory(), false); + LOG.debug("Use HTTPS: keystore={}, truststore={}", keystore, truststore); + } + server.start(); + LOG.info("MockWebServer started"); + } + + @Override + public void afterEach(ExtensionContext extensionContext) throws Exception { + if (server != null) { + server.shutdown(); + server = null; + LOG.info("MockWebServer shutdown"); + } + } + + public void enqueueResponses(int count) { + IntStream.range(0, count).forEach(i -> { + server.enqueue(new MockResponse().setResponseCode(200)); + }); + } + + public MockWebServer getServer() { + return server; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private boolean useHttps; + private String keystore; + private String keystorePassword; + private String truststore; + private String truststorePassword; + + public Builder useHttps() { + useHttps = true; + return this; + } + + public Builder withKeystore(String store, String password) { + this.keystore = store; + this.keystorePassword = password; + return this; + } + + public Builder withTruststore(String store, String password) { + this.truststore = store; + this.truststorePassword = password; + return this; + } + + public MockWebService build() { + MockWebService service = new MockWebService(); + service.useHttps = this.useHttps; + service.keystore = this.keystore; + service.keystorePassword = this.keystorePassword; + service.truststore = this.truststore; + service.truststorePassword = this.truststorePassword; + return service; + } + } +} diff --git a/tests/itests-https/src/test/java/org/apache/camel/kafkaconnector/https/sink/CamelSinkHTTPSITCase.java b/tests/itests-https/src/test/java/org/apache/camel/kafkaconnector/https/sink/CamelSinkHTTPSITCase.java index 90b7089..20bb066 100644 --- a/tests/itests-https/src/test/java/org/apache/camel/kafkaconnector/https/sink/CamelSinkHTTPSITCase.java +++ b/tests/itests-https/src/test/java/org/apache/camel/kafkaconnector/https/sink/CamelSinkHTTPSITCase.java @@ -17,10 +17,7 @@ package org.apache.camel.kafkaconnector.https.sink; -import java.io.IOException; -import java.net.InetAddress; import java.net.URL; -import java.security.KeyStore; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -29,21 +26,17 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.IntStream; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; - -import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.apache.camel.kafkaconnector.common.ConnectorPropertyFactory; +import org.apache.camel.kafkaconnector.common.services.mockweb.MockWebService; import org.apache.camel.kafkaconnector.common.test.CamelSinkTestSupport; -import org.apache.camel.kafkaconnector.common.utils.NetworkUtils; import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,9 +47,11 @@ import static org.junit.jupiter.api.Assertions.fail; public class CamelSinkHTTPSITCase extends CamelSinkTestSupport { private static final Logger LOG = LoggerFactory.getLogger(CamelSinkHTTPSITCase.class); - private final String host = NetworkUtils.getHostname(); - private final int port = NetworkUtils.getFreePort(host); - + @RegisterExtension + public final MockWebService mockWebService = MockWebService.builder() + .useHttps() + .withKeystore("/server-keystore.jks", "secret") + .build(); private MockWebServer mockServer; private String topicName; @@ -73,35 +68,10 @@ public class CamelSinkHTTPSITCase extends CamelSinkTestSupport { public void setUp() throws Exception { topicName = getTopicForTest(this); - setupHttpsMockServer(); + mockServer = mockWebService.getServer(); received = Collections.emptyList(); } - private void setupHttpsMockServer() throws Exception { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(getClass().getResourceAsStream("/server-keystore.jks"), "secret".toCharArray()); - KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmFactory.init(keyStore, "secret".toCharArray()); - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmFactory.getKeyManagers(), null, null); - mockServer = new MockWebServer(); - mockServer.useHttps(sslContext.getSocketFactory(), false); - } - - private void startMockServer() throws IOException { - IntStream.range(0, expect).forEach(i -> { - mockServer.enqueue(new MockResponse().setResponseCode(200)); - }); - mockServer.start(InetAddress.getByName(host), port); - } - - @AfterEach - public void tearDown() throws Exception { - if (mockServer != null) { - mockServer.shutdown(); - } - } - @Override protected void consumeMessages(CountDownLatch latch) { try { @@ -142,7 +112,7 @@ public class CamelSinkHTTPSITCase extends CamelSinkTestSupport { @Test @Timeout(60) public void testBasicSendReceive() throws Exception { - startMockServer(); + mockWebService.enqueueResponses(expect); String uri = mockServer.getHostName() + ":" + mockServer.getPort() + "/ckc"; ConnectorPropertyFactory connectorPropertyFactory = CamelHTTPSPropertyFactory.basic() @@ -159,7 +129,7 @@ public class CamelSinkHTTPSITCase extends CamelSinkTestSupport { @Timeout(60) @Disabled("HTTPS-sink-connector duplicates protocol #1077") public void testBasicSendReceiveHttpUriWithQueryString() throws Exception { - startMockServer(); + mockWebService.enqueueResponses(expect); String uri = mockServer.getHostName() + ":" + mockServer.getPort() + "/ckc?aaa=xxx&bbb=yyy&ccc=zzz"; ConnectorPropertyFactory connectorPropertyFactory = CamelHTTPSPropertyFactory.basic() @@ -176,7 +146,7 @@ public class CamelSinkHTTPSITCase extends CamelSinkTestSupport { @Test @Timeout(60) public void testBasicSendReceiveUsingUrl() throws Exception { - startMockServer(); + mockWebService.enqueueResponses(expect); ConnectorPropertyFactory connectorPropertyFactory = CamelHTTPSPropertyFactory.basic() .withTopics(topicName) diff --git a/tests/itests-netty-http/src/test/java/org/apache/camel/kafkaconnector/nettyhttp/sink/CamelSinkNettyhttpITCase.java b/tests/itests-netty-http/src/test/java/org/apache/camel/kafkaconnector/nettyhttp/sink/CamelSinkNettyhttpITCase.java index 96bd27a..dc8675f 100644 --- a/tests/itests-netty-http/src/test/java/org/apache/camel/kafkaconnector/nettyhttp/sink/CamelSinkNettyhttpITCase.java +++ b/tests/itests-netty-http/src/test/java/org/apache/camel/kafkaconnector/nettyhttp/sink/CamelSinkNettyhttpITCase.java @@ -20,15 +20,15 @@ package org.apache.camel.kafkaconnector.nettyhttp.sink; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.apache.camel.kafkaconnector.common.ConnectorPropertyFactory; +import org.apache.camel.kafkaconnector.common.services.mockweb.MockWebService; import org.apache.camel.kafkaconnector.common.test.CamelSinkTestSupport; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +38,8 @@ import static org.junit.jupiter.api.Assertions.fail; public class CamelSinkNettyhttpITCase extends CamelSinkTestSupport { private static final Logger LOG = LoggerFactory.getLogger(CamelSinkNettyhttpITCase.class); + @RegisterExtension + public final MockWebService mockWebService = MockWebService.builder().build(); private MockWebServer mockServer; private String topicName; @@ -53,17 +55,10 @@ public class CamelSinkNettyhttpITCase extends CamelSinkTestSupport { @BeforeEach public void setUp() { topicName = getTopicForTest(this); - mockServer = new MockWebServer(); + mockServer = mockWebService.getServer(); received = null; } - @AfterEach - public void tearDown() throws Exception { - if (mockServer != null) { - mockServer.shutdown(); - } - } - @Override protected void consumeMessages(CountDownLatch latch) { try { @@ -89,24 +84,24 @@ public class CamelSinkNettyhttpITCase extends CamelSinkTestSupport { @Test @Timeout(30) public void testBasicSendReceive() throws Exception { + mockWebService.enqueueResponses(expect); ConnectorPropertyFactory connectorPropertyFactory = CamelNettyhttpPropertyFactory.basic() .withTopics(topicName) .withProtocol("http") .withHost(mockServer.getHostName()) .withPort(mockServer.getPort()) .withPath("test"); - mockServer.enqueue(new MockResponse().setResponseCode(200)); runTest(connectorPropertyFactory, topicName, expect); } @Test @Timeout(30) public void testBasicSendReceiveUsingUrl() throws Exception { + mockWebService.enqueueResponses(expect); ConnectorPropertyFactory connectorPropertyFactory = CamelNettyhttpPropertyFactory.basic() .withTopics(topicName) .withUrl("http", mockServer.getHostName(), mockServer.getPort(), "test") .buildUrl(); - mockServer.enqueue(new MockResponse().setResponseCode(200)); runTest(connectorPropertyFactory, topicName, expect); } }
