From 593b4e1fc8cc0fb7dd96ee077ef803c4366d8eb0 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Tue, 24 Aug 2021 16:29:00 +0300 Subject: [PATCH] Lift restriction of HTTP application for Kubernetes manifest generation Resolves: #19442 --- .../deployment/OpenshiftProcessor.java | 8 +- .../image/s2i/deployment/S2iProcessor.java | 8 +- .../deployment/KubernetesCommonHelper.java | 6 +- .../deployment/KubernetesProcessor.java | 5 - .../deployment/OpenshiftProcessor.java | 2 +- integration-tests/kubernetes/pom.xml | 1 + .../quarkus-standard-way-kafka/pom.xml | 227 ++++++++++++++++++ .../it/kubernetes/kafka/DummyProcessor.java | 22 ++ .../kubernetes/kafka/BasicKubernetesTest.java | 68 ++++++ .../kubernetes/kafka/BasicMinikubeTest.java | 66 +++++ .../kubernetes/kafka/BasicOpenshiftTest.java | 71 ++++++ .../kubernetes/kafka/DeserializationUtil.java | 65 +++++ .../resources/basic-kubernetes.properties | 7 + .../test/resources/basic-minikube.properties | 9 + .../test/resources/basic-openshift.properties | 9 + 15 files changed, 558 insertions(+), 16 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/pom.xml create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/main/java/io/quarkus/it/kubernetes/kafka/DummyProcessor.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicKubernetesTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicMinikubeTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/DeserializationUtil.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-kubernetes.properties create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-minikube.properties create mode 100644 integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-openshift.properties diff --git a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java index f1ccacd608f65..ba234d4c4ac61 100644 --- a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java +++ b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java @@ -233,9 +233,9 @@ public void openshiftBuildFromJar(OpenshiftConfig openshiftConfig, .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) .findFirst(); - if (!openshiftYml.isPresent()) { + if (openshiftYml.isEmpty()) { LOG.warn( - "No Openshift manifests were generated (most likely due to the fact that the service is not an HTTP service) so no openshift process will be taking place"); + "No Openshift manifests were generated so no openshift build process will be taking place"); return; } @@ -298,9 +298,9 @@ public void openshiftBuildFromNative(OpenshiftConfig openshiftConfig, S2iConfig .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) .findFirst(); - if (!openshiftYml.isPresent()) { + if (openshiftYml.isEmpty()) { LOG.warn( - "No Openshift manifests were generated (most likely due to the fact that the service is not an HTTP service) so no openshift process will be taking place"); + "No Openshift manifests were generated so no openshift build process will be taking place"); return; } //The contextRoot is where inside the tarball we will add the jars. A null value means everything will be added under '/' while "target" means everything will be added under '/target'. diff --git a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java index 2bfae9e97043e..fb9aff6596f06 100644 --- a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java +++ b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java @@ -184,9 +184,9 @@ public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerI .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) .findFirst(); - if (!openshiftYml.isPresent()) { + if (openshiftYml.isEmpty()) { LOG.warn( - "No Openshift manifests were generated (most likely due to the fact that the service is not an HTTP service) so no s2i process will be taking place"); + "No Openshift manifests were generated so no s2i process will be taking place"); return; } @@ -224,9 +224,9 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain .filter(r -> r.getName().endsWith("kubernetes" + File.separator + "openshift.yml")) .findFirst(); - if (!openshiftYml.isPresent()) { + if (openshiftYml.isEmpty()) { LOG.warn( - "No Openshift manifests were generated (most likely due to the fact that the service is not an HTTP service) so no s2i process will be taking place"); + "No Openshift manifests were generated so no s2i process will be taking place"); return; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 76ececeee141f..7e3b6aca5fa51 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -176,8 +176,10 @@ public static List createDecorators(Optional projec result.addAll(createArgsDecorator(project, target, name, config, command)); //Handle Probes - result.addAll(createProbeDecorators(name, target, config.getLivenessProbe(), config.getReadinessProbe(), - livenessProbePath, readinessProbePath)); + if (!ports.isEmpty()) { + result.addAll(createProbeDecorators(name, target, config.getLivenessProbe(), config.getReadinessProbe(), + livenessProbePath, readinessProbePath)); + } //Handle RBAC if (!roleBindings.isEmpty()) { diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java index 8082edf501a05..0f8251b1cc906 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java @@ -96,11 +96,6 @@ public void build(ApplicationInfoBuildItem applicationInfo, List allConfigurationRegistry = new ArrayList<>(configurators); List allDecorators = new ArrayList<>(decorators); - if (kubernetesPorts.isEmpty()) { - log.debug("The service is not an HTTP service so no Kubernetes manifests will be generated"); - return; - } - final Path root; try { root = Files.createTempDirectory("quarkus-kubernetes"); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index e1f36f3945d7a..0d9df43328048 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -198,7 +198,7 @@ public List createDecorators(ApplicationInfoBuildItem applic .findFirst().orElse(DEFAULT_HTTP_PORT); result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyHttpGetActionPortDecorator(name, name, port))); - // Hanlde non-s2i + // Handle non-s2i if (!capabilities.isPresent(Capability.CONTAINER_IMAGE_S2I) && !capabilities.isPresent("io.quarkus.openshift") && !capabilities.isPresent(Capability.CONTAINER_IMAGE_OPENSHIFT)) { diff --git a/integration-tests/kubernetes/pom.xml b/integration-tests/kubernetes/pom.xml index 3b8f2f7a5c391..501c2770b8cd4 100644 --- a/integration-tests/kubernetes/pom.xml +++ b/integration-tests/kubernetes/pom.xml @@ -15,6 +15,7 @@ maven-invoker-way quarkus-standard-way + quarkus-standard-way-kafka diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/pom.xml b/integration-tests/kubernetes/quarkus-standard-way-kafka/pom.xml new file mode 100644 index 0000000000000..a43d7649c9c63 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/pom.xml @@ -0,0 +1,227 @@ + + + 4.0.0 + + + io.quarkus + quarkus-integration-test-kubernetes-parent + 999-SNAPSHOT + + + quarkus-integration-test-kubernetes-standard-kafka + Quarkus - Integration Tests - Kubernetes - Standard - Kafka + Kubernetes integration tests that use @QuarkusProdModeTest for dummy Kafka messaing only application + + + + + quarkus-container-image-docker-deployment, + quarkus-container-image-jib-deployment, + quarkus-container-image-openshift-deployment, + quarkus-container-image-s2i-deployment + + + + + + io.quarkus + quarkus-smallrye-reactive-messaging-kafka + + + io.quarkus + quarkus-kubernetes + + + io.quarkus + quarkus-junit5-internal + test + + + org.assertj + assertj-core + test + + + io.fabric8 + kubernetes-model + test + + + javax.annotation + javax.annotation-api + + + javax.xml.bind + jaxb-api + + + jakarta.xml.bind + jakarta.xml.bind-api + + + + + io.fabric8 + knative-model + test + + + javax.annotation + javax.annotation-api + + + javax.xml.bind + jaxb-api + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + test + + + javax.annotation + javax.annotation-api + + + javax.xml.bind + jaxb-api + + + + + jakarta.annotation + jakarta.annotation-api + test + + + org.jboss.spec.javax.xml.bind + jboss-jaxb-api_2.3_spec + test + + + io.rest-assured + rest-assured + test + + + org.awaitility + awaitility + test + + + + + io.quarkus + quarkus-kubernetes-spi + test + + + * + * + + + + + + + io.quarkus + quarkus-smallrye-reactive-messaging-kafka-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-kubernetes-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-container-image-docker-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-container-image-jib-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-container-image-openshift-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-container-image-s2i-deployment + ${project.version} + pom + test + + + * + * + + + + + + + + basic-test-suite + + + basicTests + + + + true + + + + + diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/main/java/io/quarkus/it/kubernetes/kafka/DummyProcessor.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/main/java/io/quarkus/it/kubernetes/kafka/DummyProcessor.java new file mode 100644 index 0000000000000..edc846d2eafad --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/main/java/io/quarkus/it/kubernetes/kafka/DummyProcessor.java @@ -0,0 +1,22 @@ +package io.quarkus.it.kubernetes.kafka; + +import java.util.Random; + +import org.eclipse.microprofile.reactive.messaging.Incoming; +import org.eclipse.microprofile.reactive.messaging.Outgoing; + +import io.smallrye.common.annotation.Blocking; + +public class DummyProcessor { + + private final Random random = new Random(); + + @Incoming("requests") + @Outgoing("quotes") + @Blocking + public int process(String quoteRequest) throws InterruptedException { + // simulate some hard working task + Thread.sleep(200); + return random.nextInt(100); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicKubernetesTest.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicKubernetesTest.java new file mode 100644 index 0000000000000..3a4450954f6ae --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicKubernetesTest.java @@ -0,0 +1,68 @@ +package io.quarkus.it.kubernetes.kafka; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class BasicKubernetesTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(DummyProcessor.class)) + .setApplicationName("basic") + .setApplicationVersion("0.1-SNAPSHOT") + .withConfigurationResource("basic-kubernetes.properties"); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")) + .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2)); + List kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + assertThat(kubernetesList).hasSize(1); + + assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo("basic"); + assertThat(m.getNamespace()).isNull(); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getSelector()).isNotNull().satisfies(labelSelector -> { + assertThat(labelSelector.getMatchLabels()).containsOnly(entry("app.kubernetes.io/name", "basic"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + }); + + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getImagePullPolicy()).isEqualTo("Always"); + assertThat(container.getPorts()).isNullOrEmpty(); + }); + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicMinikubeTest.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicMinikubeTest.java new file mode 100644 index 0000000000000..41d24d358aee4 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicMinikubeTest.java @@ -0,0 +1,66 @@ +package io.quarkus.it.kubernetes.kafka; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class BasicMinikubeTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(DummyProcessor.class)) + .setApplicationName("minikube-with-defaults") + .setApplicationVersion("0.1-SNAPSHOT") + .withConfigurationResource("basic-minikube.properties") + .setForcedDependencies( + Collections.singletonList(new AppArtifact("io.quarkus", "quarkus-minikube", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("minikube.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("minikube.yml")) + .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2)); + List kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("minikube.yml")); + + assertThat(kubernetesList).singleElement().isInstanceOfSatisfying(Deployment.class, d -> { + + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getNamespace()).isNull(); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getReplicas()).isEqualTo(1); + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getImagePullPolicy()).isEqualTo("IfNotPresent"); + assertThat(container.getPorts()).isNullOrEmpty(); + }); + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java new file mode 100644 index 0000000000000..d907871ba898e --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/BasicOpenshiftTest.java @@ -0,0 +1,71 @@ +package io.quarkus.it.kubernetes.kafka; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.assertj.core.api.AbstractObjectAssert; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.PodTemplateSpec; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class BasicOpenshiftTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(DummyProcessor.class)) + .setApplicationName("basic-openshift") + .setApplicationVersion("0.1-SNAPSHOT") + .withConfigurationResource("basic-openshift.properties"); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @SuppressWarnings("unchecked") + @Test + public void assertGeneratedResources() throws IOException { + Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("openshift.yml")) + .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2)); + List openshiftList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("openshift.yml")); + + assertThat(openshiftList).filteredOn(h -> "DeploymentConfig".equals(h.getKind())).singleElement().satisfies(h -> { + assertThat(h.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo("basic-openshift"); + assertThat(m.getLabels().get("app.openshift.io/runtime")).isEqualTo("quarkus"); + assertThat(m.getNamespace()).isNull(); + }); + AbstractObjectAssert specAssert = assertThat(h).extracting("spec"); + specAssert.extracting("replicas").isEqualTo(1); + specAssert.extracting("triggers").isInstanceOfSatisfying(Collection.class, c -> { + assertThat(c).isEmpty(); + }); + specAssert.extracting("selector").isInstanceOfSatisfying(Map.class, selectorsMap -> { + assertThat(selectorsMap).containsOnly(entry("app.kubernetes.io/name", "basic-openshift"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + }); + specAssert.extracting("template").isInstanceOfSatisfying(PodTemplateSpec.class, templateMap -> { + assertThat(templateMap.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getPorts()).isNullOrEmpty(); + }); + }); + }); + }); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/DeserializationUtil.java b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/DeserializationUtil.java new file mode 100644 index 0000000000000..c86e3eb1f3b0b --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/java/io/quarkus/it/kubernetes/kafka/DeserializationUtil.java @@ -0,0 +1,65 @@ +package io.quarkus.it.kubernetes.kafka; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +import io.fabric8.kubernetes.api.model.HasMetadata; + +// TODO: as this is a copy of the class in the 'quarkus-integration-test-kubernetes-standard', +// maybe we should create a new kubernetes test module to contain this class? +final class DeserializationUtil { + + private static final String DOCUMENT_DELIMITER = "---"; + static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory()); + + private DeserializationUtil() { + } + + /** + * Takes a YAML file as input and output a list of Kubernetes resources + * present in the file + * The list is sorted alphabetically based on the resource Kind + */ + public static List deserializeAsList(Path yamlFilePath) throws IOException { + String[] parts = splitDocument(Files.readAllLines(yamlFilePath, StandardCharsets.UTF_8).toArray(new String[0])); + List items = new ArrayList<>(); + for (String part : parts) { + if (part.trim().isEmpty()) { + continue; + } + items.add(MAPPER.readValue(part, HasMetadata.class)); + } + items.sort(Comparator.comparing(HasMetadata::getKind)); + return items; + } + + static String[] splitDocument(String[] lines) { + List documents = new ArrayList<>(); + int nLine = 0; + StringBuilder builder = new StringBuilder(); + + while (nLine < lines.length) { + if (lines[nLine].length() < DOCUMENT_DELIMITER.length() + || !lines[nLine].substring(0, DOCUMENT_DELIMITER.length()).equals(DOCUMENT_DELIMITER)) { + builder.append(lines[nLine]).append(System.lineSeparator()); + } else { + documents.add(builder.toString()); + builder.setLength(0); + } + + nLine++; + } + + if (!builder.toString().isEmpty()) + documents.add(builder.toString()); + return documents.toArray(new String[0]); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-kubernetes.properties b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-kubernetes.properties new file mode 100644 index 0000000000000..f7c694380a316 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-kubernetes.properties @@ -0,0 +1,7 @@ +# Configure the incoming `quote-requests` Kafka topic +mp.messaging.incoming.requests.connector=smallrye-kafka +mp.messaging.incoming.requests.topic=quote-requests +mp.messaging.incoming.requests.auto.offset.reset=earliest + +# Configure the outgoing `quotes` Kafka topic +mp.messaging.outgoing.quotes.connector=smallrye-kafka diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-minikube.properties b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-minikube.properties new file mode 100644 index 0000000000000..c81f822dee726 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-minikube.properties @@ -0,0 +1,9 @@ +quarkus.kubernetes.deployment-target=minikube + +# Configure the incoming `quote-requests` Kafka topic +mp.messaging.incoming.requests.connector=smallrye-kafka +mp.messaging.incoming.requests.topic=quote-requests +mp.messaging.incoming.requests.auto.offset.reset=earliest + +# Configure the outgoing `quotes` Kafka topic +mp.messaging.outgoing.quotes.connector=smallrye-kafka diff --git a/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-openshift.properties b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-openshift.properties new file mode 100644 index 0000000000000..152bb28d271af --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way-kafka/src/test/resources/basic-openshift.properties @@ -0,0 +1,9 @@ +quarkus.kubernetes.deployment-target=openshift + +# Configure the incoming `quote-requests` Kafka topic +mp.messaging.incoming.requests.connector=smallrye-kafka +mp.messaging.incoming.requests.topic=quote-requests +mp.messaging.incoming.requests.auto.offset.reset=earliest + +# Configure the outgoing `quotes` Kafka topic +mp.messaging.outgoing.quotes.connector=smallrye-kafka