diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle index abe8f0e0f35..426a515062e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle @@ -14,4 +14,5 @@ dependencies { testImplementation("org.springframework.kafka:spring-kafka-test") { exclude group: "commons-logging", module: "commons-logging" } + testImplementation("org.testcontainers:junit-jupiter") } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/Consumer.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/Consumer.java index 4beb1a980ff..3daf110da70 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/Consumer.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/Consumer.java @@ -23,7 +23,7 @@ import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @Component -class Consumer { +public class Consumer { private final List messages = new CopyOnWriteArrayList<>(); @@ -33,7 +33,7 @@ class Consumer { System.out.println("Received sample message [" + message + "]"); } - List getMessages() { + public List getMessages() { return this.messages; } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/ssl/SampleKafkaSslApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/ssl/SampleKafkaSslApplication.java new file mode 100644 index 00000000000..30b8c8ad2e3 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/main/java/smoketest/kafka/ssl/SampleKafkaSslApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * 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 + * + * https://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 smoketest.kafka.ssl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleKafkaSslApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleKafkaSslApplication.class, args); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/java/smoketest/kafka/ssl/SampleKafkaSslApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/java/smoketest/kafka/ssl/SampleKafkaSslApplicationTests.java new file mode 100644 index 00000000000..2d239233f4f --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/java/smoketest/kafka/ssl/SampleKafkaSslApplicationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * 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 + * + * https://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 smoketest.kafka.ssl; + +import java.io.File; +import java.time.Duration; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import smoketest.kafka.Consumer; +import smoketest.kafka.Producer; +import smoketest.kafka.SampleMessage; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.not; + +@Testcontainers +@SpringBootTest(classes = { SampleKafkaSslApplication.class, Producer.class, Consumer.class }, + properties = { "spring.kafka.security.protocol=SSL", "spring.kafka.bootstrap-servers=localhost:9093", + "spring.kafka.ssl.bundle=client", + "spring.ssl.bundle.jks.client.keystore.location=classpath:ssl/test-client.p12", + "spring.ssl.bundle.jks.client.keystore.password=password", + "spring.ssl.bundle.jks.client.truststore.location=classpath:ssl/test-ca.p12", + "spring.ssl.bundle.jks.client.truststore.password=password" }) +class SampleKafkaSslApplicationTests { + + private static final File KAFKA_COMPOSE_FILE = new File("src/test/resources/docker-compose.yml"); + + private static final String KAFKA_COMPOSE_SERVICE = "kafka"; + + private static final int KAFKA_SSL_PORT = 9093; + + @Container + public DockerComposeContainer container = new DockerComposeContainer<>(KAFKA_COMPOSE_FILE) + .withExposedService(KAFKA_COMPOSE_SERVICE, KAFKA_SSL_PORT, Wait.forListeningPorts(KAFKA_SSL_PORT)); + + @Autowired + private Producer producer; + + @Autowired + private Consumer consumer; + + @Test + void testVanillaExchange() { + this.producer.send(new SampleMessage(1, "A simple test message")); + + Awaitility.waitAtMost(Duration.ofSeconds(30)).until(this.consumer::getMessages, not(empty())); + assertThat(this.consumer.getMessages()).extracting("message").containsOnly("A simple test message"); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/docker-compose.yml b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/docker-compose.yml new file mode 100644 index 00000000000..326e5a30c03 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/docker-compose.yml @@ -0,0 +1,30 @@ +--- +version: '2' +services: + zookeeper: + image: confluentinc/cp-zookeeper:7.4.0 + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + + kafka: + image: confluentinc/cp-kafka:7.4.0 + depends_on: + - zookeeper + ports: + - "9092:9092" + - "9093:9093" + environment: + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,SSL://localhost:9093 + KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true' + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + KAFKA_SSL_CLIENT_AUTH: "required" + KAFKA_SSL_KEYSTORE_FILENAME: '/certs/test-server.p12' + KAFKA_SSL_KEYSTORE_CREDENTIALS: '/certs/credentials' + KAFKA_SSL_KEY_CREDENTIALS: '/certs/credentials' + KAFKA_SSL_TRUSTSTORE_FILENAME: '/certs/test-ca.p12' + KAFKA_SSL_TRUSTSTORE_CREDENTIALS: '/certs/credentials' + volumes: + - ./ssl/:/etc/kafka/secrets/certs diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/credentials b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/credentials new file mode 100644 index 00000000000..7aa311adf93 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/credentials @@ -0,0 +1 @@ +password \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-ca.p12 b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-ca.p12 new file mode 100644 index 00000000000..fd0a5d99b0c Binary files /dev/null and b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-ca.p12 differ diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-client.p12 b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-client.p12 new file mode 100644 index 00000000000..d2fd1d0f322 Binary files /dev/null and b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-client.p12 differ diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-server.p12 b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-server.p12 new file mode 100644 index 00000000000..5f1bd89eccf Binary files /dev/null and b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/src/test/resources/ssl/test-server.p12 differ