This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.8.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.8.x by this push:
new 87baf70c2ac CAMEL-21533: camel-jbang - Backport Knative test coverage
to 4.8.x (#16529)
87baf70c2ac is described below
commit 87baf70c2ac8f55f366727257ffb770e24731106
Author: Thomas Diesler <[email protected]>
AuthorDate: Wed Dec 11 20:32:35 2024 +0100
CAMEL-21533: camel-jbang - Backport Knative test coverage to 4.8.x (#16529)
* CAMEL-21530: camel-jbang - Remove deps on runtime and cluster-type where
no longer needed
* CAMEL-21533: camel-jbang - Backport Knative test coverage to 4.8.x
---
.../kubernetes/KubernetesExportBaseTest.java | 65 +++-
.../kubernetes/KubernetesExportKnativeTest.java | 299 +++++++++++++++++
.../commands/kubernetes/KubernetesExportTest.java | 353 +--------------------
3 files changed, 355 insertions(+), 362 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportBaseTest.java
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportBaseTest.java
index 748cbdd90cd..bfb2f3a244a 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportBaseTest.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportBaseTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.dsl.jbang.core.commands.kubernetes;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -32,10 +33,16 @@ import java.util.Properties;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.apps.Deployment;
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.fabric8.openshift.api.model.Route;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import org.apache.camel.dsl.jbang.core.common.RuntimeType;
import org.apache.camel.util.IOHelper;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import picocli.CommandLine;
@@ -71,16 +78,50 @@ public class KubernetesExportBaseTest extends
KubernetesBaseTest {
return command;
}
- protected boolean hasService(RuntimeType rt, ClusterType ct) throws
IOException {
- return getResource(rt, ct, Service.class).isPresent();
+ protected Properties getApplicationProperties(File workingDir) throws
IOException {
+ String content = readResource(workingDir,
"src/main/resources/application.properties");
+ Properties applicationProperties = new Properties();
+ applicationProperties.load(new
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
+ return applicationProperties;
+ }
+
+ protected Deployment getDeployment(RuntimeType rt) throws IOException {
+ return getResource(rt, Deployment.class)
+ .orElseThrow(() -> new RuntimeCamelException("Cannot find
deployment for: %s".formatted(rt.runtime())));
+ }
+
+ protected Ingress getIngress(RuntimeType rt) throws IOException {
+ return getResource(rt, Ingress.class)
+ .orElseThrow(() -> new RuntimeCamelException("Cannot find
ingress for: %s".formatted(rt.runtime())));
+ }
+
+ protected boolean hasIngress(RuntimeType rt) throws IOException {
+ return getResource(rt, Ingress.class).isPresent();
+ }
+
+ protected boolean hasKnativeService(RuntimeType rt) throws IOException {
+ return getResource(rt,
io.fabric8.knative.serving.v1.Service.class).isPresent();
+ }
+
+ protected Route getRoute(RuntimeType rt) throws IOException {
+ return getResource(rt, Route.class)
+ .orElseThrow(() -> new RuntimeCamelException("Cannot find
route for: %s".formatted(rt.runtime())));
+ }
+
+ protected boolean hasRoute(RuntimeType rt) throws IOException {
+ return getResource(rt, Route.class).isPresent();
+ }
+
+ protected Service getService(RuntimeType rt) throws IOException {
+ return getResource(rt, Service.class)
+ .orElseThrow(() -> new RuntimeCamelException("Cannot find
service for: %s".formatted(rt.runtime())));
}
- protected boolean hasKnativeService(RuntimeType rt, ClusterType ct) throws
IOException {
- return getResource(rt, ct,
io.fabric8.knative.serving.v1.Service.class).isPresent();
+ protected boolean hasService(RuntimeType rt) throws IOException {
+ return getResource(rt, Service.class).isPresent();
}
- protected <T extends HasMetadata> Optional<T> getResource(RuntimeType rt,
ClusterType ct, Class<T> type)
- throws IOException {
+ protected <T extends HasMetadata> Optional<T> getResource(RuntimeType rt,
Class<T> type) throws IOException {
var kind = type.getSimpleName().toLowerCase();
File file = new File(workingDir,
"src/main/jkube/%s.yml".formatted(kind));
if (file.isFile()) {
@@ -101,10 +142,12 @@ public class KubernetesExportBaseTest extends
KubernetesBaseTest {
}
}
- protected Properties getApplicationProperties(File workingDir) throws
IOException {
- String content = readResource(workingDir,
"src/main/resources/application.properties");
- Properties applicationProperties = new Properties();
- applicationProperties.load(new
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
- return applicationProperties;
+ protected Model readMavenModel() throws Exception {
+ File f = workingDir.toPath().resolve("pom.xml").toFile();
+ Assertions.assertTrue(f.isFile(), "Not a pom.xml file: " + f);
+ MavenXpp3Reader mavenReader = new MavenXpp3Reader();
+ Model model = mavenReader.read(new FileReader(f));
+ model.setPomFile(f);
+ return model;
}
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
new file mode 100644
index 00000000000..8115f0fac31
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
@@ -0,0 +1,299 @@
+/*
+ * 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.dsl.jbang.core.commands.kubernetes;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Stream;
+
+import io.fabric8.knative.eventing.v1.Trigger;
+import io.fabric8.knative.messaging.v1.Subscription;
+import io.fabric8.knative.sources.v1.SinkBinding;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.BaseTrait;
+import org.apache.camel.dsl.jbang.core.common.RuntimeType;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
+ disabledReason = "Requires too much network
resources")
+public class KubernetesExportKnativeTest extends KubernetesExportBaseTest {
+
+ private static Stream<Arguments> runtimeProvider() {
+ return Stream.of(
+ Arguments.of(RuntimeType.main),
+ Arguments.of(RuntimeType.springBoot),
+ Arguments.of(RuntimeType.quarkus));
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeServiceSpec(RuntimeType rt) throws Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:route-service.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+
+ command.traits = new String[] {
+ "knative-service.enabled=true",
+ "knative-service.class=hpa.autoscaling.knative.dev",
+ "knative-service.autoscaling-metric=cpu",
+ "knative-service.autoscaling-target=80",
+ "knative-service.min-scale=1",
+ "knative-service.max-scale=10",
+ "knative-service.rollout-duration=60",
+ "knative-service.visibility=cluster-local",
+ "knative-service.timeout-seconds=300" };
+ int exit = command.doCall();
+ Assertions.assertEquals(0, exit);
+
+ Assertions.assertFalse(hasService(rt));
+ Assertions.assertTrue(hasKnativeService(rt));
+
+ io.fabric8.knative.serving.v1.Service service
+ = getResource(rt, io.fabric8.knative.serving.v1.Service.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing
Knative service in Kubernetes manifest"));
+
+ Map<String, String> labelsA = service.getMetadata().getLabels();
+ var labelsB =
service.getSpec().getTemplate().getMetadata().getLabels();
+ Map<String, String> annotations =
service.getSpec().getTemplate().getMetadata().getAnnotations();
+ Assertions.assertEquals("route-service",
service.getMetadata().getName());
+ Assertions.assertEquals(3, labelsA.size());
+ Assertions.assertEquals("route-service",
labelsA.get(BaseTrait.KUBERNETES_LABEL_NAME));
+ Assertions.assertEquals("true",
labelsA.get("bindings.knative.dev/include"));
+ Assertions.assertEquals("cluster-local",
labelsA.get("networking.knative.dev/visibility"));
+ Assertions.assertEquals(1,
service.getMetadata().getAnnotations().size());
+ Assertions.assertEquals("60",
service.getMetadata().getAnnotations().get("serving.knative.dev/rolloutDuration"));
+ Assertions.assertEquals(1, labelsB.size());
+ Assertions.assertEquals("route-service",
labelsB.get(BaseTrait.KUBERNETES_LABEL_NAME));
+ Assertions.assertEquals(5, annotations.size());
+ Assertions.assertEquals("cpu",
annotations.get("autoscaling.knative.dev/metric"));
+ Assertions.assertEquals("hpa.autoscaling.knative.dev",
annotations.get("autoscaling.knative.dev/class"));
+ Assertions.assertEquals("80",
annotations.get("autoscaling.knative.dev/target"));
+ Assertions.assertEquals("1",
annotations.get("autoscaling.knative.dev/minScale"));
+ Assertions.assertEquals("10",
annotations.get("autoscaling.knative.dev/maxScale"));
+ Assertions.assertEquals(300,
service.getSpec().getTemplate().getSpec().getTimeoutSeconds());
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeTrigger(RuntimeType rt) throws Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:knative-event-source.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+ int exit = command.doCall();
+ Assertions.assertEquals(0, exit);
+
+ Assertions.assertTrue(hasService(rt));
+ Assertions.assertFalse(hasKnativeService(rt));
+
+ Trigger trigger = getResource(rt, Trigger.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing Knative
trigger in Kubernetes manifest"));
+
+ Assertions.assertEquals("my-broker-knative-event-source-camel-event",
trigger.getMetadata().getName());
+ Assertions.assertEquals("my-broker", trigger.getSpec().getBroker());
+ Assertions.assertEquals(1,
trigger.getSpec().getFilter().getAttributes().size());
+ Assertions.assertEquals("camel-event",
trigger.getSpec().getFilter().getAttributes().get("type"));
+ Assertions.assertEquals("knative-event-source",
trigger.getSpec().getSubscriber().getRef().getName());
+ Assertions.assertEquals("Service",
trigger.getSpec().getSubscriber().getRef().getKind());
+ Assertions.assertEquals("v1",
trigger.getSpec().getSubscriber().getRef().getApiVersion());
+ Assertions.assertEquals("/events/camel-event",
trigger.getSpec().getSubscriber().getUri());
+
+ Properties applicationProperties =
getApplicationProperties(workingDir);
+ Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
+
+ Assertions.assertEquals("""
+ {
+ "resources" : [ {
+ "name" : "camel-event",
+ "type" : "event",
+ "endpointKind" : "source",
+ "path" : "/events/camel-event",
+ "objectApiVersion" : "eventing.knative.dev/v1",
+ "objectKind" : "Broker",
+ "objectName" : "my-broker",
+ "reply" : false
+ } ]
+ }
+ """, getKnativeResourceConfiguration(workingDir));
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeSubscription(RuntimeType rt) throws Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:knative-channel-source.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+ command.doCall();
+
+ Assertions.assertTrue(hasService(rt));
+ Assertions.assertFalse(hasKnativeService(rt));
+
+ Subscription subscription = getResource(rt, Subscription.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing Knative
subscription in Kubernetes manifest"));
+
+ Assertions.assertEquals("my-channel-knative-channel-source",
subscription.getMetadata().getName());
+ Assertions.assertEquals("my-channel",
subscription.getSpec().getChannel().getName());
+ Assertions.assertEquals("knative-channel-source",
subscription.getSpec().getSubscriber().getRef().getName());
+ Assertions.assertEquals("Service",
subscription.getSpec().getSubscriber().getRef().getKind());
+ Assertions.assertEquals("v1",
subscription.getSpec().getSubscriber().getRef().getApiVersion());
+ Assertions.assertEquals("/channels/my-channel",
subscription.getSpec().getSubscriber().getUri());
+
+ Properties applicationProperties =
getApplicationProperties(workingDir);
+ Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
+
+ Assertions.assertEquals("""
+ {
+ "resources" : [ {
+ "name" : "my-channel",
+ "type" : "channel",
+ "endpointKind" : "source",
+ "path" : "/channels/my-channel",
+ "objectApiVersion" : "messaging.knative.dev/v1",
+ "objectKind" : "Channel",
+ "objectName" : "my-channel",
+ "reply" : false
+ } ]
+ }
+ """, getKnativeResourceConfiguration(workingDir));
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeBrokerSinkBinding(RuntimeType rt) throws
Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:knative-event-sink.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+ command.doCall();
+
+ Assertions.assertTrue(hasService(rt));
+ Assertions.assertFalse(hasKnativeService(rt));
+
+ SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
+
+ Assertions.assertEquals("knative-event-sink",
sinkBinding.getMetadata().getName());
+ Assertions.assertEquals("my-broker",
sinkBinding.getSpec().getSink().getRef().getName());
+ Assertions.assertEquals("Broker",
sinkBinding.getSpec().getSink().getRef().getKind());
+ Assertions.assertEquals("eventing.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
+ Assertions.assertEquals("knative-event-sink",
sinkBinding.getSpec().getSubject().getName());
+ Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
+ Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
+
+ Properties applicationProperties =
getApplicationProperties(workingDir);
+ Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
+
+ Assertions.assertEquals("""
+ {
+ "resources" : [ {
+ "name" : "my-broker",
+ "type" : "event",
+ "endpointKind" : "sink",
+ "url" : "{{k.sink:http://localhost:8080}}",
+ "objectApiVersion" : "eventing.knative.dev/v1",
+ "objectKind" : "Broker",
+ "objectName" : "my-broker",
+ "reply" : false
+ } ]
+ }
+ """, getKnativeResourceConfiguration(workingDir));
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeChannelSinkBinding(RuntimeType rt) throws
Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:knative-channel-sink.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+ command.doCall();
+
+ Assertions.assertTrue(hasService(rt));
+ Assertions.assertFalse(hasKnativeService(rt));
+
+ SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
+
+ Assertions.assertEquals("knative-channel-sink",
sinkBinding.getMetadata().getName());
+ Assertions.assertEquals("my-channel",
sinkBinding.getSpec().getSink().getRef().getName());
+ Assertions.assertEquals("Channel",
sinkBinding.getSpec().getSink().getRef().getKind());
+ Assertions.assertEquals("messaging.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
+ Assertions.assertEquals("knative-channel-sink",
sinkBinding.getSpec().getSubject().getName());
+ Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
+ Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
+
+ Properties applicationProperties =
getApplicationProperties(workingDir);
+ Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
+
+ Assertions.assertEquals("""
+ {
+ "resources" : [ {
+ "name" : "my-channel",
+ "type" : "channel",
+ "endpointKind" : "sink",
+ "url" : "{{k.sink:http://localhost:8080}}",
+ "objectApiVersion" : "messaging.knative.dev/v1",
+ "objectKind" : "Channel",
+ "objectName" : "my-channel",
+ "reply" : false
+ } ]
+ }
+ """, getKnativeResourceConfiguration(workingDir));
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ public void shouldAddKnativeEndpointSinkBinding(RuntimeType rt) throws
Exception {
+ KubernetesExport command = createCommand(new String[] {
"classpath:knative-endpoint-sink.yaml" },
+ "--image-group=camel-test", "--runtime=" + rt.runtime());
+ command.doCall();
+
+ Assertions.assertTrue(hasService(rt));
+ Assertions.assertFalse(hasKnativeService(rt));
+
+ SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
+ .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
+
+ Assertions.assertEquals("knative-endpoint-sink",
sinkBinding.getMetadata().getName());
+ Assertions.assertEquals("my-endpoint",
sinkBinding.getSpec().getSink().getRef().getName());
+ Assertions.assertEquals("Service",
sinkBinding.getSpec().getSink().getRef().getKind());
+ Assertions.assertEquals("serving.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
+ Assertions.assertEquals("knative-endpoint-sink",
sinkBinding.getSpec().getSubject().getName());
+ Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
+ Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
+
+ Properties applicationProperties =
getApplicationProperties(workingDir);
+ Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
+
+ Assertions.assertEquals("""
+ {
+ "resources" : [ {
+ "name" : "my-endpoint",
+ "type" : "endpoint",
+ "endpointKind" : "sink",
+ "url" : "{{k.sink:http://localhost:8080}}",
+ "objectApiVersion" : "serving.knative.dev/v1",
+ "objectKind" : "Service",
+ "objectName" : "my-endpoint",
+ "reply" : false
+ } ]
+ }
+ """, getKnativeResourceConfiguration(workingDir));
+ }
+
+ private String getKnativeResourceConfiguration(File workingDir) throws
IOException {
+ return readResource(workingDir, "src/main/resources/knative.json");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java
index a30066d078e..cb411fbb10e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java
@@ -17,33 +17,21 @@
package org.apache.camel.dsl.jbang.core.commands.kubernetes;
-import java.io.ByteArrayInputStream;
-import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.List;
-import java.util.Optional;
import java.util.Properties;
import java.util.stream.Stream;
-import io.fabric8.knative.eventing.v1.Trigger;
-import io.fabric8.knative.messaging.v1.Subscription;
-import io.fabric8.knative.sources.v1.SinkBinding;
import io.fabric8.kubernetes.api.model.Container;
-import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServicePort;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
import io.fabric8.openshift.api.model.Route;
-import org.apache.camel.RuntimeCamelException;
import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.BaseTrait;
import org.apache.camel.dsl.jbang.core.common.RuntimeType;
import org.apache.camel.util.IOHelper;
import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import org.junit.jupiter.params.ParameterizedTest;
@@ -194,7 +182,7 @@ class KubernetesExportTest extends KubernetesExportBaseTest
{
@MethodSource("runtimeProvider")
public void shouldAddIngressSpec(RuntimeType rt) throws Exception {
KubernetesExport command = createCommand(new String[] {
"classpath:route-service.yaml" },
- "--trait-profile", "kubernetes",
+ "--cluster-type", "kubernetes",
"--trait", "ingress.enabled=true",
"--trait", "ingress.host=example.com",
"--trait", "ingress.path=/something(/|$)(.*)",
@@ -245,7 +233,7 @@ class KubernetesExportTest extends KubernetesExportBaseTest
{
String certificate = IOHelper.loadText(new
FileInputStream("src/test/resources/route/tls.pem"));
String key = IOHelper.loadText(new
FileInputStream("src/test/resources/route/tls.key"));
KubernetesExport command = createCommand(new String[] {
"classpath:route-service.yaml" },
- "--trait-profile", "openshift",
+ "--cluster-type", "openshift",
"--trait", "route.enabled=true",
"--trait", "route.host=example.com",
"--trait", "route.tls-termination=edge",
@@ -330,252 +318,6 @@ class KubernetesExportTest extends
KubernetesExportBaseTest {
Assertions.assertEquals("custom",
service.getSpec().getPorts().get(0).getTargetPort().getStrVal());
}
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeServiceSpec(RuntimeType rt) throws Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:route-service.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
-
- command.traits = new String[] {
- "knative-service.enabled=true",
- "knative-service.class=hpa.autoscaling.knative.dev",
- "knative-service.autoscaling-metric=cpu",
- "knative-service.autoscaling-target=80",
- "knative-service.min-scale=1",
- "knative-service.max-scale=10",
- "knative-service.rollout-duration=60",
- "knative-service.visibility=cluster-local" };
- command.doCall();
-
- Assertions.assertFalse(hasService(rt));
- Assertions.assertTrue(hasKnativeService(rt));
-
- io.fabric8.knative.serving.v1.Service service = getResource(rt,
io.fabric8.knative.serving.v1.Service.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
service in Kubernetes manifest"));
-
- Assertions.assertEquals("route-service",
service.getMetadata().getName());
- Assertions.assertEquals(3, service.getMetadata().getLabels().size());
- Assertions.assertEquals("route-service",
service.getMetadata().getLabels().get(BaseTrait.KUBERNETES_LABEL_NAME));
- Assertions.assertEquals("true",
service.getMetadata().getLabels().get("bindings.knative.dev/include"));
- Assertions.assertEquals("cluster-local",
service.getMetadata().getLabels().get("networking.knative.dev/visibility"));
- Assertions.assertEquals(1,
service.getMetadata().getAnnotations().size());
- Assertions.assertEquals("60",
service.getMetadata().getAnnotations().get("serving.knative.dev/rolloutDuration"));
- Assertions.assertEquals(1,
service.getSpec().getTemplate().getMetadata().getLabels().size());
- Assertions.assertEquals("route-service",
-
service.getSpec().getTemplate().getMetadata().getLabels().get(BaseTrait.KUBERNETES_LABEL_NAME));
- Assertions.assertEquals(5,
service.getSpec().getTemplate().getMetadata().getAnnotations().size());
- Assertions.assertEquals("cpu",
-
service.getSpec().getTemplate().getMetadata().getAnnotations().get("autoscaling.knative.dev/metric"));
- Assertions.assertEquals("hpa.autoscaling.knative.dev",
-
service.getSpec().getTemplate().getMetadata().getAnnotations().get("autoscaling.knative.dev/class"));
- Assertions.assertEquals("80",
-
service.getSpec().getTemplate().getMetadata().getAnnotations().get("autoscaling.knative.dev/target"));
- Assertions.assertEquals("1",
-
service.getSpec().getTemplate().getMetadata().getAnnotations().get("autoscaling.knative.dev/minScale"));
- Assertions.assertEquals("10",
-
service.getSpec().getTemplate().getMetadata().getAnnotations().get("autoscaling.knative.dev/maxScale"));
- }
-
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeTrigger(RuntimeType rt) throws Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:knative-event-source.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
- command.doCall();
-
- Assertions.assertTrue(hasService(rt));
- Assertions.assertFalse(hasKnativeService(rt));
-
- Trigger trigger = getResource(rt, Trigger.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
trigger in Kubernetes manifest"));
-
- Assertions.assertEquals("my-broker-knative-event-source-camel-event",
trigger.getMetadata().getName());
- Assertions.assertEquals("my-broker", trigger.getSpec().getBroker());
- Assertions.assertEquals(1,
trigger.getSpec().getFilter().getAttributes().size());
- Assertions.assertEquals("camel-event",
trigger.getSpec().getFilter().getAttributes().get("type"));
- Assertions.assertEquals("knative-event-source",
trigger.getSpec().getSubscriber().getRef().getName());
- Assertions.assertEquals("Service",
trigger.getSpec().getSubscriber().getRef().getKind());
- Assertions.assertEquals("v1",
trigger.getSpec().getSubscriber().getRef().getApiVersion());
- Assertions.assertEquals("/events/camel-event",
trigger.getSpec().getSubscriber().getUri());
-
- Properties applicationProperties =
getApplicationProperties(workingDir);
- Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
-
- Assertions.assertEquals("""
- {
- "resources" : [ {
- "name" : "camel-event",
- "type" : "event",
- "endpointKind" : "source",
- "path" : "/events/camel-event",
- "objectApiVersion" : "eventing.knative.dev/v1",
- "objectKind" : "Broker",
- "objectName" : "my-broker",
- "reply" : false
- } ]
- }
- """, getKnativeResourceConfiguration(workingDir));
- }
-
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeSubscription(RuntimeType rt) throws Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:knative-channel-source.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
- command.doCall();
-
- Assertions.assertTrue(hasService(rt));
- Assertions.assertFalse(hasKnativeService(rt));
-
- Subscription subscription = getResource(rt, Subscription.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
subscription in Kubernetes manifest"));
-
- Assertions.assertEquals("my-channel-knative-channel-source",
subscription.getMetadata().getName());
- Assertions.assertEquals("my-channel",
subscription.getSpec().getChannel().getName());
- Assertions.assertEquals("knative-channel-source",
subscription.getSpec().getSubscriber().getRef().getName());
- Assertions.assertEquals("Service",
subscription.getSpec().getSubscriber().getRef().getKind());
- Assertions.assertEquals("v1",
subscription.getSpec().getSubscriber().getRef().getApiVersion());
- Assertions.assertEquals("/channels/my-channel",
subscription.getSpec().getSubscriber().getUri());
-
- Properties applicationProperties =
getApplicationProperties(workingDir);
- Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
-
- Assertions.assertEquals("""
- {
- "resources" : [ {
- "name" : "my-channel",
- "type" : "channel",
- "endpointKind" : "source",
- "path" : "/channels/my-channel",
- "objectApiVersion" : "messaging.knative.dev/v1",
- "objectKind" : "Channel",
- "objectName" : "my-channel",
- "reply" : false
- } ]
- }
- """, getKnativeResourceConfiguration(workingDir));
- }
-
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeBrokerSinkBinding(RuntimeType rt) throws
Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:knative-event-sink.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
- command.doCall();
-
- Assertions.assertTrue(hasService(rt));
- Assertions.assertFalse(hasKnativeService(rt));
-
- SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
-
- Assertions.assertEquals("knative-event-sink",
sinkBinding.getMetadata().getName());
- Assertions.assertEquals("my-broker",
sinkBinding.getSpec().getSink().getRef().getName());
- Assertions.assertEquals("Broker",
sinkBinding.getSpec().getSink().getRef().getKind());
- Assertions.assertEquals("eventing.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
- Assertions.assertEquals("knative-event-sink",
sinkBinding.getSpec().getSubject().getName());
- Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
- Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
-
- Properties applicationProperties =
getApplicationProperties(workingDir);
- Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
-
- Assertions.assertEquals("""
- {
- "resources" : [ {
- "name" : "my-broker",
- "type" : "event",
- "endpointKind" : "sink",
- "url" : "{{k.sink:http://localhost:8080}}",
- "objectApiVersion" : "eventing.knative.dev/v1",
- "objectKind" : "Broker",
- "objectName" : "my-broker",
- "reply" : false
- } ]
- }
- """, getKnativeResourceConfiguration(workingDir));
- }
-
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeChannelSinkBinding(RuntimeType rt) throws
Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:knative-channel-sink.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
- command.doCall();
-
- Assertions.assertTrue(hasService(rt));
- Assertions.assertFalse(hasKnativeService(rt));
-
- SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
-
- Assertions.assertEquals("knative-channel-sink",
sinkBinding.getMetadata().getName());
- Assertions.assertEquals("my-channel",
sinkBinding.getSpec().getSink().getRef().getName());
- Assertions.assertEquals("Channel",
sinkBinding.getSpec().getSink().getRef().getKind());
- Assertions.assertEquals("messaging.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
- Assertions.assertEquals("knative-channel-sink",
sinkBinding.getSpec().getSubject().getName());
- Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
- Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
-
- Properties applicationProperties =
getApplicationProperties(workingDir);
- Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
-
- Assertions.assertEquals("""
- {
- "resources" : [ {
- "name" : "my-channel",
- "type" : "channel",
- "endpointKind" : "sink",
- "url" : "{{k.sink:http://localhost:8080}}",
- "objectApiVersion" : "messaging.knative.dev/v1",
- "objectKind" : "Channel",
- "objectName" : "my-channel",
- "reply" : false
- } ]
- }
- """, getKnativeResourceConfiguration(workingDir));
- }
-
- @ParameterizedTest
- @MethodSource("runtimeProvider")
- public void shouldAddKnativeEndpointSinkBinding(RuntimeType rt) throws
Exception {
- KubernetesExport command = createCommand(new String[] {
"classpath:knative-endpoint-sink.yaml" },
- "--image-group=camel-test", "--runtime=" + rt.runtime());
- command.doCall();
-
- Assertions.assertTrue(hasService(rt));
- Assertions.assertFalse(hasKnativeService(rt));
-
- SinkBinding sinkBinding = getResource(rt, SinkBinding.class)
- .orElseThrow(() -> new RuntimeCamelException("Missing Knative
sinkBinding in Kubernetes manifest"));
-
- Assertions.assertEquals("knative-endpoint-sink",
sinkBinding.getMetadata().getName());
- Assertions.assertEquals("my-endpoint",
sinkBinding.getSpec().getSink().getRef().getName());
- Assertions.assertEquals("Service",
sinkBinding.getSpec().getSink().getRef().getKind());
- Assertions.assertEquals("serving.knative.dev/v1",
sinkBinding.getSpec().getSink().getRef().getApiVersion());
- Assertions.assertEquals("knative-endpoint-sink",
sinkBinding.getSpec().getSubject().getName());
- Assertions.assertEquals("Deployment",
sinkBinding.getSpec().getSubject().getKind());
- Assertions.assertEquals("apps/v1",
sinkBinding.getSpec().getSubject().getApiVersion());
-
- Properties applicationProperties =
getApplicationProperties(workingDir);
- Assertions.assertEquals("classpath:knative.json",
applicationProperties.get("camel.component.knative.environmentPath"));
-
- Assertions.assertEquals("""
- {
- "resources" : [ {
- "name" : "my-endpoint",
- "type" : "endpoint",
- "endpointKind" : "sink",
- "url" : "{{k.sink:http://localhost:8080}}",
- "objectApiVersion" : "serving.knative.dev/v1",
- "objectKind" : "Service",
- "objectName" : "my-endpoint",
- "reply" : false
- } ]
- }
- """, getKnativeResourceConfiguration(workingDir));
- }
-
@ParameterizedTest
@MethodSource("runtimeProvider")
public void shouldAddVolumes(RuntimeType rt) throws Exception {
@@ -743,95 +485,4 @@ class KubernetesExportTest extends
KubernetesExportBaseTest {
Assertions.assertEquals("quay.io/camel/demo-app:1.0",
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage());
}
-
- private Deployment getDeployment(RuntimeType rt) throws IOException {
- return getResource(rt, Deployment.class)
- .orElseThrow(() -> new RuntimeCamelException("Cannot find
deployment for: %s".formatted(rt.runtime())));
- }
-
- private Service getService(RuntimeType rt) throws IOException {
- return getResource(rt, Service.class)
- .orElseThrow(() -> new RuntimeCamelException("Cannot find
service for: %s".formatted(rt.runtime())));
- }
-
- private Ingress getIngress(RuntimeType rt) throws IOException {
- return getResource(rt, Ingress.class)
- .orElseThrow(() -> new RuntimeCamelException("Cannot find
ingress for: %s".formatted(rt.runtime())));
- }
-
- private boolean hasIngress(RuntimeType rt) throws IOException {
- return getResource(rt, Ingress.class).isPresent();
- }
-
- private Route getRoute(RuntimeType rt) throws IOException {
- return getResource(rt, Route.class)
- .orElseThrow(() -> new RuntimeCamelException("Cannot find
route for: %s".formatted(rt.runtime())));
- }
-
- private boolean hasRoute(RuntimeType rt) throws IOException {
- return getResource(rt, Route.class).isPresent();
- }
-
- private boolean hasService(RuntimeType rt) throws IOException {
- return getResource(rt, Service.class).isPresent();
- }
-
- private boolean hasKnativeService(RuntimeType rt) throws IOException {
- return getResource(rt,
io.fabric8.knative.serving.v1.Service.class).isPresent();
- }
-
- private <T extends HasMetadata> Optional<T> getResource(RuntimeType rt,
Class<T> type) throws IOException {
- if (rt == RuntimeType.quarkus) {
- try (FileInputStream fis
- = new FileInputStream(
-
KubernetesHelper.getKubernetesManifest(ClusterType.KUBERNETES.name(),
- new File(workingDir,
"/src/main/kubernetes")))) {
- List<HasMetadata> resources =
kubernetesClient.load(fis).items();
- return resources.stream()
- .filter(it -> type.isAssignableFrom(it.getClass()))
- .map(type::cast)
- .findFirst();
- }
- }
- if (rt == RuntimeType.springBoot || rt == RuntimeType.main) {
- var kind = type.getSimpleName().toLowerCase();
- File file = new File(workingDir,
"src/main/jkube/%s.yml".formatted(kind));
- if (file.isFile()) {
- try (FileInputStream fis = new FileInputStream(file)) {
- List<HasMetadata> resources =
kubernetesClient.load(fis).items();
- return resources.stream()
- .filter(it -> type.isAssignableFrom(it.getClass()))
- .map(type::cast)
- .findFirst();
- }
- }
- }
- return Optional.empty();
- }
-
- protected String readResource(File workingDir, String path) throws
IOException {
- try (FileInputStream fis = new
FileInputStream(workingDir.toPath().resolve(path).toFile())) {
- return IOHelper.loadText(fis);
- }
- }
-
- protected Properties getApplicationProperties(File workingDir) throws
IOException {
- String content = readResource(workingDir,
"src/main/resources/application.properties");
- Properties applicationProperties = new Properties();
- applicationProperties.load(new
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
- return applicationProperties;
- }
-
- private String getKnativeResourceConfiguration(File workingDir) throws
IOException {
- return readResource(workingDir, "src/main/resources/knative.json");
- }
-
- private Model readMavenModel() throws Exception {
- File f = workingDir.toPath().resolve("pom.xml").toFile();
- Assertions.assertTrue(f.isFile(), "Not a pom.xml file: " + f);
- MavenXpp3Reader mavenReader = new MavenXpp3Reader();
- Model model = mavenReader.read(new FileReader(f));
- model.setPomFile(f);
- return model;
- }
}