You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ts...@apache.org on 2022/09/14 01:52:07 UTC

[camel-k] branch main updated (b1c320ab9 -> 151def156)

This is an automated email from the ASF dual-hosted git repository.

tsato pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git


    from b1c320ab9 fix: release as an action
     new f3d576443 fix(metadata): add error handling on metadata extraction
     new 1bb2a6c82 feat(metadata): raise error when capability/dependency not resolved in CamelCatalog
     new 28550fcac fix(trait): traits for Initialization phase should not trigger at platform setup action
     new ffc6b7d17 feat(controller): set integration phase to Error when traits application failed
     new c0ac5a167 chore(controller): small refactoring of integration controller
     new 06d6300b4 fix(controller): monitor should reconcile integrations in initialisation failed condition
     new 151def156 fix(e2e): add E2E test for reconcilation of integrations in initialisation failed condition

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 addons/keda/keda.go                                |   6 +-
 addons/keda/keda_test.go                           |  49 ++++----
 addons/master/master.go                            |   5 +-
 addons/resume/resume.go                            |   5 +-
 e2e/global/common/files/BadRoute.java              |  11 +-
 e2e/global/common/files/Java.java                  |  14 +--
 .../files/Java.java => files/Unresolvable.java}    |   5 +-
 e2e/global/common/integration_fail_test.go         |  33 +++++-
 e2e/global/common/operator_metrics_test.go         |   5 +-
 pkg/apis/camel/v1/camelcatalog_types_support.go    |  12 ++
 pkg/apis/camel/v1/integration_types.go             |   6 +-
 pkg/apis/camel/v1/integration_types_support.go     |  23 ++++
 pkg/cmd/local/local.go                             |   6 +-
 pkg/controller/integration/initialize.go           |   6 +-
 .../integration/integration_controller.go          |  45 ++++---
 pkg/controller/integration/monitor.go              | 104 ++++++++++-------
 pkg/controller/integration/monitor_cronjob.go      |  19 ++-
 pkg/controller/integration/monitor_deployment.go   |  14 ++-
 pkg/controller/integration/monitor_knative.go      |   8 +-
 pkg/controller/integration/platform_setup.go       |   7 ++
 pkg/metadata/metadata.go                           |  31 +++--
 pkg/metadata/metadata_capabilities_test.go         |   5 +-
 pkg/metadata/metadata_dependencies_test.go         | 130 ++++++++++++++-------
 pkg/metadata/metadata_http_test.go                 |  54 +++++----
 pkg/metadata/metadata_uri_test.go                  |  93 ++++++++-------
 pkg/trait/cron.go                                  |   6 +-
 pkg/trait/dependencies.go                          |  13 ++-
 pkg/trait/kamelets.go                              |   4 +-
 pkg/trait/kamelets_test.go                         |  41 +++----
 pkg/trait/knative.go                               |  36 ++++--
 pkg/trait/knative_service.go                       |  10 +-
 pkg/trait/knative_service_test.go                  |  21 ++--
 pkg/trait/mount_test.go                            |   9 +-
 pkg/trait/platform.go                              |  94 ++++++++-------
 pkg/trait/platform_test.go                         |   2 +-
 pkg/trait/service.go                               |   5 +-
 pkg/trait/util.go                                  |  10 +-
 pkg/util/kamelets/util.go                          |   7 +-
 pkg/util/source/inspector.go                       | 112 +++++++++++++-----
 pkg/util/source/inspector_groovy.go                |  20 +---
 pkg/util/source/inspector_java_script.go           |  20 +---
 pkg/util/source/inspector_java_source.go           |  20 +---
 pkg/util/source/inspector_kotlin.go                |  20 +---
 pkg/util/source/inspector_xml.go                   |  14 ++-
 pkg/util/source/inspector_yaml.go                  |  16 ++-
 .../source/{inspector_kamelet.go => kamelet.go}    |   0
 pkg/util/source/types.go                           |  16 ++-
 47 files changed, 722 insertions(+), 470 deletions(-)
 copy e2e/global/common/{traits/files/Java.java => files/Unresolvable.java} (90%)
 rename pkg/util/source/{inspector_kamelet.go => kamelet.go} (100%)


[camel-k] 04/07: feat(controller): set integration phase to Error when traits application failed

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit ffc6b7d176d506d9b5e94f5f7cba2244bd498826
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Sep 13 14:30:05 2022 +0900

    feat(controller): set integration phase to Error when traits application failed
---
 e2e/global/common/files/BadRoute.java              | 11 ++---
 e2e/global/common/files/Java.java                  | 14 +++----
 .../files/{BadRoute.java => Unresolvable.java}     | 17 ++++----
 e2e/global/common/integration_fail_test.go         | 26 +++++++++++-
 pkg/apis/camel/v1/integration_types.go             |  2 +
 pkg/apis/camel/v1/integration_types_support.go     | 23 ++++++++++
 pkg/controller/integration/initialize.go           |  6 ++-
 .../integration/integration_controller.go          | 30 ++++++++-----
 pkg/controller/integration/monitor.go              | 49 +++++++++++-----------
 pkg/controller/integration/monitor_cronjob.go      | 19 ++++++---
 pkg/controller/integration/monitor_deployment.go   | 14 +++++--
 pkg/controller/integration/monitor_knative.go      |  8 ++--
 12 files changed, 148 insertions(+), 71 deletions(-)

diff --git a/e2e/global/common/files/BadRoute.java b/e2e/global/common/files/BadRoute.java
index 9967879cb..dc2e42343 100644
--- a/e2e/global/common/files/BadRoute.java
+++ b/e2e/global/common/files/BadRoute.java
@@ -20,9 +20,10 @@ import java.lang.Override;
 import org.apache.camel.builder.RouteBuilder;
 
 public class BadRoute extends RouteBuilder {
-  @Override
-  public void configure() throws Exception {
-    from("mongodb:sample?database=sampledb&collection=mycollection&operation=findfoo").throwException(new RuntimeException("Heyyy")).log("bar");
-  }
+    @Override
+    public void configure() throws Exception {
+        from("mongodb:sample?database=sampledb&collection=mycollection&operation=findfoo")
+            .throwException(new RuntimeException("Heyyy"))
+            .log("bar");
+    }
 }
-
diff --git a/e2e/global/common/files/Java.java b/e2e/global/common/files/Java.java
index 66fef5fe8..30b1f459e 100644
--- a/e2e/global/common/files/Java.java
+++ b/e2e/global/common/files/Java.java
@@ -18,11 +18,11 @@
 import org.apache.camel.builder.RouteBuilder;
 
 public class Java extends RouteBuilder {
-  @Override
-  public void configure() throws Exception {
-	  from("timer:tick")
-	  .setHeader("m").constant("string!")
-	  .setBody().simple("Magic${header.m}")
-      .log("${body}");
-  }
+    @Override
+    public void configure() throws Exception {
+        from("timer:tick")
+            .setHeader("m").constant("string!")
+            .setBody().simple("Magic${header.m}")
+            .log("${body}");
+    }
 }
diff --git a/e2e/global/common/files/BadRoute.java b/e2e/global/common/files/Unresolvable.java
similarity index 73%
copy from e2e/global/common/files/BadRoute.java
copy to e2e/global/common/files/Unresolvable.java
index 9967879cb..768f32ad4 100644
--- a/e2e/global/common/files/BadRoute.java
+++ b/e2e/global/common/files/Unresolvable.java
@@ -15,14 +15,15 @@
  * limitations under the License.
  */
 
-import java.lang.Exception;
-import java.lang.Override;
 import org.apache.camel.builder.RouteBuilder;
 
-public class BadRoute extends RouteBuilder {
-  @Override
-  public void configure() throws Exception {
-    from("mongodb:sample?database=sampledb&collection=mycollection&operation=findfoo").throwException(new RuntimeException("Heyyy")).log("bar");
-  }
+public class Unresolvable extends RouteBuilder {
+    @Override
+    public void configure() throws Exception {
+        from("timer:tick")
+            .setHeader("m").constant("string!")
+            .setBody().simple("Magic${header.m}")
+            .log("${body}")
+            .to("non-existent:hello");
+    }
 }
-
diff --git a/e2e/global/common/integration_fail_test.go b/e2e/global/common/integration_fail_test.go
index c95b691b1..0f498ac84 100644
--- a/e2e/global/common/integration_fail_test.go
+++ b/e2e/global/common/integration_fail_test.go
@@ -24,6 +24,7 @@ package common
 
 import (
 	"testing"
+	"time"
 
 	. "github.com/onsi/gomega"
 	"github.com/onsi/gomega/gstruct"
@@ -44,7 +45,8 @@ func TestBadRouteIntegration(t *testing.T) {
 			Expect(KamelRunWithID(operatorID, ns, "files/BadRoute.java", "--name", name).Execute()).To(Succeed())
 			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
 			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionFalse))
 
 			// Make sure the Integration can be scaled
 			Expect(ScaleIntegration(ns, name, 2)).To(Succeed())
@@ -63,7 +65,8 @@ func TestBadRouteIntegration(t *testing.T) {
 		t.Run("run missing dependency java route", func(t *testing.T) {
 			RegisterTestingT(t)
 			name := "java-route"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, "-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed())
+			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
+				"-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed())
 			// Integration in error
 			Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
 			kitName := IntegrationKit(ns, name)()
@@ -77,5 +80,24 @@ func TestBadRouteIntegration(t *testing.T) {
 			// Clean up
 			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 		})
+
+		t.Run("run unresolvable component java route", func(t *testing.T) {
+			RegisterTestingT(t)
+			name := "unresolvable-route"
+			Expect(KamelRunWithID(operatorID, ns, "files/Unresolvable.java", "--name", name).Execute()).To(Succeed())
+			// Integration in error
+			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionFalse))
+			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
+				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
+				WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
+			))
+			// Kit shouldn't be created
+			Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
+
+			// Clean up
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
 	})
 }
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index c6f1e750e..921b2d74f 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -240,6 +240,8 @@ const (
 	// IntegrationConditionErrorReason --
 	IntegrationConditionErrorReason string = "Error"
 
+	// IntegrationConditionInitializationFailedReason --
+	IntegrationConditionInitializationFailedReason string = "InitializationFailed"
 	// IntegrationConditionUnsupportedLanguageReason --
 	IntegrationConditionUnsupportedLanguageReason string = "UnsupportedLanguage"
 
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 50316a081..3885b9211 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -322,6 +322,29 @@ func (in *Integration) GetIntegrationKitNamespace(p *IntegrationPlatform) string
 	return in.Namespace
 }
 
+// IsConditionTrue checks if the condition with the given type is true.
+func (in *Integration) IsConditionTrue(conditionType IntegrationConditionType) bool {
+	if in == nil {
+		return false
+	}
+	cond := in.Status.GetCondition(conditionType)
+	if cond == nil {
+		return false
+	}
+
+	return cond.Status == corev1.ConditionTrue
+}
+
+// SetReadyCondition sets Ready condition with the given status, reason, and message.
+func (in *Integration) SetReadyCondition(status corev1.ConditionStatus, reason, message string) {
+	in.Status.SetCondition(IntegrationConditionReady, status, reason, message)
+}
+
+// SetReadyConditionError sets Ready condition to False with the given error message.
+func (in *Integration) SetReadyConditionError(err string) {
+	in.SetReadyCondition(corev1.ConditionFalse, IntegrationConditionErrorReason, err)
+}
+
 // GetCondition returns the condition with the provided type.
 func (in *IntegrationStatus) GetCondition(condType IntegrationConditionType) *IntegrationCondition {
 	for i := range in.Conditions {
diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go
index 8feddee9e..58cf23cb9 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -20,6 +20,7 @@ package integration
 import (
 	"context"
 
+	corev1 "k8s.io/api/core/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
@@ -51,7 +52,10 @@ func (action *initializeAction) CanHandle(integration *v1.Integration) bool {
 // Handle handles the integrations.
 func (action *initializeAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
 	if _, err := trait.Apply(ctx, action.client, integration, nil); err != nil {
-		return nil, err
+		integration.Status.Phase = v1.IntegrationPhaseError
+		integration.SetReadyCondition(corev1.ConditionFalse,
+			v1.IntegrationConditionInitializationFailedReason, err.Error())
+		return integration, err
 	}
 
 	if integration.Status.IntegrationKit == nil {
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index bd9a19937..d898ff3ea 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -344,22 +344,18 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile.
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
 				camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
+				// Update the integration (mostly just to update its phase) if the new instance is returned
+				if newTarget != nil {
+					_ = r.update(ctx, &instance, newTarget, &targetLog)
+				}
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
-				if err := r.update(ctx, &instance, newTarget); err != nil {
+				if err := r.update(ctx, &instance, newTarget, &targetLog); err != nil {
 					camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return reconcile.Result{}, err
 				}
-
-				if newTarget.Status.Phase != instance.Status.Phase {
-					targetLog.Info(
-						"state transition",
-						"phase-from", instance.Status.Phase,
-						"phase-to", newTarget.Status.Phase,
-					)
-				}
 			}
 
 			// handle one action at time so the resource
@@ -372,7 +368,7 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile.
 	return reconcile.Result{}, nil
 }
 
-func (r *reconcileIntegration) update(ctx context.Context, base *v1.Integration, target *v1.Integration) error {
+func (r *reconcileIntegration) update(ctx context.Context, base *v1.Integration, target *v1.Integration, log *log.Logger) error {
 	d, err := digest.ComputeForIntegration(target)
 	if err != nil {
 		return err
@@ -381,5 +377,17 @@ func (r *reconcileIntegration) update(ctx context.Context, base *v1.Integration,
 	target.Status.Digest = d
 	target.Status.ObservedGeneration = base.Generation
 
-	return r.client.Status().Patch(ctx, target, ctrl.MergeFrom(base))
+	if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(base)); err != nil {
+		return err
+	}
+
+	if target.Status.Phase != base.Status.Phase {
+		log.Info(
+			"state transition",
+			"phase-from", base.Status.Phase,
+			"phase-to", target.Status.Phase,
+		)
+	}
+
+	return nil
 }
diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index df8f426f3..9909be03e 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -57,11 +57,28 @@ func (action *monitorAction) Name() string {
 }
 
 func (action *monitorAction) CanHandle(integration *v1.Integration) bool {
+	// When in InitializationFailed condition a kit is not available for the integration
+	// so the monitor action is not able to handle it.
+	if isInInitializationFailed(integration.Status) {
+		return false
+	}
+
 	return integration.Status.Phase == v1.IntegrationPhaseDeploying ||
 		integration.Status.Phase == v1.IntegrationPhaseRunning ||
 		integration.Status.Phase == v1.IntegrationPhaseError
 }
 
+func isInInitializationFailed(status v1.IntegrationStatus) bool {
+	if status.Phase == v1.IntegrationPhaseError {
+		cond := status.GetCondition(v1.IntegrationConditionReady)
+		if cond.Status == corev1.ConditionFalse && cond.Reason == v1.IntegrationConditionInitializationFailedReason {
+			return true
+		}
+	}
+
+	return false
+}
+
 func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
 	// At that staged the Integration must have a Kit
 	if integration.Status.IntegrationKit == nil {
@@ -177,7 +194,7 @@ func (action *monitorAction) newController(env *trait.Environment, integration *
 	var controller controller
 	var obj ctrl.Object
 	switch {
-	case isConditionTrue(integration, v1.IntegrationConditionDeploymentAvailable):
+	case integration.IsConditionTrue(v1.IntegrationConditionDeploymentAvailable):
 		obj = getUpdatedController(env, &appsv1.Deployment{})
 		deploy, ok := obj.(*appsv1.Deployment)
 		if !ok {
@@ -187,7 +204,7 @@ func (action *monitorAction) newController(env *trait.Environment, integration *
 			obj:         deploy,
 			integration: integration,
 		}
-	case isConditionTrue(integration, v1.IntegrationConditionKnativeServiceAvailable):
+	case integration.IsConditionTrue(v1.IntegrationConditionKnativeServiceAvailable):
 		obj = getUpdatedController(env, &servingv1.Service{})
 		svc, ok := obj.(*servingv1.Service)
 		if !ok {
@@ -197,7 +214,7 @@ func (action *monitorAction) newController(env *trait.Environment, integration *
 			obj:         svc,
 			integration: integration,
 		}
-	case isConditionTrue(integration, v1.IntegrationConditionCronJobAvailable):
+	case integration.IsConditionTrue(v1.IntegrationConditionCronJobAvailable):
 		obj = getUpdatedController(env, &batchv1.CronJob{})
 		cj, ok := obj.(*batchv1.CronJob)
 		if !ok {
@@ -257,7 +274,7 @@ func checkPodStatuses(integration *v1.Integration, pendingPods []corev1.Pod, run
 		// Check the scheduled condition
 		if scheduled := kubernetes.GetPodCondition(pod, corev1.PodScheduled); scheduled != nil && scheduled.Status == corev1.ConditionFalse && scheduled.Reason == "Unschedulable" {
 			integration.Status.Phase = v1.IntegrationPhaseError
-			setReadyConditionError(integration, scheduled.Message)
+			integration.SetReadyConditionError(scheduled.Message)
 			return true
 		}
 	}
@@ -270,7 +287,7 @@ func checkPodStatuses(integration *v1.Integration, pendingPods []corev1.Pod, run
 			// Check the images are pulled
 			if waiting := container.State.Waiting; waiting != nil && waiting.Reason == "ImagePullBackOff" {
 				integration.Status.Phase = v1.IntegrationPhaseError
-				setReadyConditionError(integration, waiting.Message)
+				integration.SetReadyConditionError(waiting.Message)
 				return true
 			}
 		}
@@ -287,12 +304,12 @@ func checkPodStatuses(integration *v1.Integration, pendingPods []corev1.Pod, run
 			// Check the container state
 			if waiting := container.State.Waiting; waiting != nil && waiting.Reason == "CrashLoopBackOff" {
 				integration.Status.Phase = v1.IntegrationPhaseError
-				setReadyConditionError(integration, waiting.Message)
+				integration.SetReadyConditionError(waiting.Message)
 				return true
 			}
 			if terminated := container.State.Terminated; terminated != nil && terminated.Reason == "Error" {
 				integration.Status.Phase = v1.IntegrationPhaseError
-				setReadyConditionError(integration, terminated.Message)
+				integration.SetReadyConditionError(terminated.Message)
 				return true
 			}
 		}
@@ -416,7 +433,7 @@ func (action *monitorAction) probeReadiness(ctx context.Context, environment *tr
 		if integration.Status.Phase == v1.IntegrationPhaseError {
 			reason = v1.IntegrationConditionErrorReason
 		}
-		setReadyCondition(integration, corev1.ConditionFalse, reason, fmt.Sprintf("%s", runtimeNotReadyMessages))
+		integration.SetReadyCondition(corev1.ConditionFalse, reason, fmt.Sprintf("%s", runtimeNotReadyMessages))
 	}
 
 	return nil
@@ -453,19 +470,3 @@ func getIntegrationContainer(environment *trait.Environment, pod *corev1.Pod) *c
 	}
 	return nil
 }
-
-func isConditionTrue(integration *v1.Integration, conditionType v1.IntegrationConditionType) bool {
-	cond := integration.Status.GetCondition(conditionType)
-	if cond == nil {
-		return false
-	}
-	return cond.Status == corev1.ConditionTrue
-}
-
-func setReadyConditionError(integration *v1.Integration, err string) {
-	setReadyCondition(integration, corev1.ConditionFalse, v1.IntegrationConditionErrorReason, err)
-}
-
-func setReadyCondition(integration *v1.Integration, status corev1.ConditionStatus, reason string, message string) {
-	integration.Status.SetCondition(v1.IntegrationConditionReady, status, reason, message)
-}
diff --git a/pkg/controller/integration/monitor_cronjob.go b/pkg/controller/integration/monitor_cronjob.go
index 203938943..baea57d5c 100644
--- a/pkg/controller/integration/monitor_cronjob.go
+++ b/pkg/controller/integration/monitor_cronjob.go
@@ -60,7 +60,9 @@ func (c *cronJobController) checkReadyCondition(ctx context.Context) (bool, erro
 		}
 		if c.lastCompletedJob != nil {
 			if failed := kubernetes.GetJobCondition(*c.lastCompletedJob, batchv1.JobFailed); failed != nil && failed.Status == corev1.ConditionTrue {
-				setReadyCondition(c.integration, corev1.ConditionFalse, v1.IntegrationConditionLastJobFailedReason, fmt.Sprintf("last job %s failed: %s", c.lastCompletedJob.Name, failed.Message))
+				c.integration.SetReadyCondition(corev1.ConditionFalse,
+					v1.IntegrationConditionLastJobFailedReason,
+					fmt.Sprintf("last job %s failed: %s", c.lastCompletedJob.Name, failed.Message))
 				c.integration.Status.Phase = v1.IntegrationPhaseError
 				return true, nil
 			}
@@ -77,25 +79,30 @@ func (c *cronJobController) getPodSpec() corev1.PodSpec {
 func (c *cronJobController) updateReadyCondition(readyPods []corev1.Pod) bool {
 	switch {
 	case c.obj.Status.LastScheduleTime == nil:
-		setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionCronJobCreatedReason, "cronjob created")
+		c.integration.SetReadyCondition(corev1.ConditionTrue,
+			v1.IntegrationConditionCronJobCreatedReason, "cronjob created")
 		return true
 
 	case len(c.obj.Status.Active) > 0:
-		setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionCronJobActiveReason, "cronjob active")
+		c.integration.SetReadyCondition(corev1.ConditionTrue,
+			v1.IntegrationConditionCronJobActiveReason, "cronjob active")
 		return true
 
 	case c.obj.Spec.SuccessfulJobsHistoryLimit != nil && *c.obj.Spec.SuccessfulJobsHistoryLimit == 0 && c.obj.Spec.FailedJobsHistoryLimit != nil && *c.obj.Spec.FailedJobsHistoryLimit == 0:
-		setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionCronJobCreatedReason, "no jobs history available")
+		c.integration.SetReadyCondition(corev1.ConditionTrue,
+			v1.IntegrationConditionCronJobCreatedReason, "no jobs history available")
 		return true
 
 	case c.lastCompletedJob != nil:
 		if complete := kubernetes.GetJobCondition(*c.lastCompletedJob, batchv1.JobComplete); complete != nil && complete.Status == corev1.ConditionTrue {
-			setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionLastJobSucceededReason, fmt.Sprintf("last job %s completed successfully", c.lastCompletedJob.Name))
+			c.integration.SetReadyCondition(corev1.ConditionTrue,
+				v1.IntegrationConditionLastJobSucceededReason,
+				fmt.Sprintf("last job %s completed successfully", c.lastCompletedJob.Name))
 			return true
 		}
 
 	default:
-		setReadyCondition(c.integration, corev1.ConditionUnknown, "", "")
+		c.integration.SetReadyCondition(corev1.ConditionUnknown, "", "")
 	}
 
 	return false
diff --git a/pkg/controller/integration/monitor_deployment.go b/pkg/controller/integration/monitor_deployment.go
index 097fa73d5..96f2b5948 100644
--- a/pkg/controller/integration/monitor_deployment.go
+++ b/pkg/controller/integration/monitor_deployment.go
@@ -39,7 +39,7 @@ func (c *deploymentController) checkReadyCondition(ctx context.Context) (bool, e
 	// Check the Deployment progression
 	if progressing := kubernetes.GetDeploymentCondition(*c.obj, appsv1.DeploymentProgressing); progressing != nil && progressing.Status == corev1.ConditionFalse && progressing.Reason == "ProgressDeadlineExceeded" {
 		c.integration.Status.Phase = v1.IntegrationPhaseError
-		setReadyConditionError(c.integration, progressing.Message)
+		c.integration.SetReadyConditionError(progressing.Message)
 		return true, nil
 	}
 
@@ -64,14 +64,20 @@ func (c *deploymentController) updateReadyCondition(readyPods []corev1.Pod) bool
 		// reported to be ready is larger than or equal to the specified number
 		// of replicas. This avoids reporting a falsy readiness condition
 		// when the Integration is being down-scaled.
-		setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionDeploymentReadyReason, fmt.Sprintf("%d/%d ready replicas", readyReplicas, replicas))
+		c.integration.SetReadyCondition(corev1.ConditionTrue,
+			v1.IntegrationConditionDeploymentReadyReason,
+			fmt.Sprintf("%d/%d ready replicas", readyReplicas, replicas))
 		return true
 
 	case c.obj.Status.UpdatedReplicas < replicas:
-		setReadyCondition(c.integration, corev1.ConditionFalse, v1.IntegrationConditionDeploymentProgressingReason, fmt.Sprintf("%d/%d updated replicas", c.obj.Status.UpdatedReplicas, replicas))
+		c.integration.SetReadyCondition(corev1.ConditionFalse,
+			v1.IntegrationConditionDeploymentProgressingReason,
+			fmt.Sprintf("%d/%d updated replicas", c.obj.Status.UpdatedReplicas, replicas))
 
 	default:
-		setReadyCondition(c.integration, corev1.ConditionFalse, v1.IntegrationConditionDeploymentProgressingReason, fmt.Sprintf("%d/%d ready replicas", readyReplicas, replicas))
+		c.integration.SetReadyCondition(corev1.ConditionFalse,
+			v1.IntegrationConditionDeploymentProgressingReason,
+			fmt.Sprintf("%d/%d ready replicas", readyReplicas, replicas))
 	}
 
 	return false
diff --git a/pkg/controller/integration/monitor_knative.go b/pkg/controller/integration/monitor_knative.go
index c8182266e..22b902ef2 100644
--- a/pkg/controller/integration/monitor_knative.go
+++ b/pkg/controller/integration/monitor_knative.go
@@ -39,7 +39,7 @@ func (c *knativeServiceController) checkReadyCondition(ctx context.Context) (boo
 	// Check the KnativeService conditions
 	if ready := kubernetes.GetKnativeServiceCondition(*c.obj, servingv1.ServiceConditionReady); ready.IsFalse() && ready.GetReason() == "RevisionFailed" {
 		c.integration.Status.Phase = v1.IntegrationPhaseError
-		setReadyConditionError(c.integration, ready.Message)
+		c.integration.SetReadyConditionError(ready.Message)
 		return true, nil
 	}
 
@@ -53,10 +53,12 @@ func (c *knativeServiceController) getPodSpec() corev1.PodSpec {
 func (c *knativeServiceController) updateReadyCondition(readyPods []corev1.Pod) bool {
 	ready := kubernetes.GetKnativeServiceCondition(*c.obj, servingv1.ServiceConditionReady)
 	if ready.IsTrue() {
-		setReadyCondition(c.integration, corev1.ConditionTrue, v1.IntegrationConditionKnativeServiceReadyReason, "")
+		c.integration.SetReadyCondition(corev1.ConditionTrue,
+			v1.IntegrationConditionKnativeServiceReadyReason, "")
 		return true
 	}
-	setReadyCondition(c.integration, corev1.ConditionFalse, ready.GetReason(), ready.GetMessage())
+	c.integration.SetReadyCondition(corev1.ConditionFalse,
+		ready.GetReason(), ready.GetMessage())
 
 	return false
 }


[camel-k] 05/07: chore(controller): small refactoring of integration controller

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit c0ac5a167be70ad6c670302fb292c3328930677c
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Sep 13 14:42:27 2022 +0900

    chore(controller): small refactoring of integration controller
---
 pkg/controller/integration/integration_controller.go | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index d898ff3ea..bc63ef92c 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -80,9 +80,8 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 func integrationUpdateFunc(old *v1.Integration, it *v1.Integration) bool {
 	// Observe the time to first readiness metric
 	previous := old.Status.GetCondition(v1.IntegrationConditionReady)
-	if next := it.Status.GetCondition(v1.IntegrationConditionReady); (previous == nil || previous.Status != corev1.ConditionTrue && (previous.FirstTruthyTime == nil || previous.FirstTruthyTime.IsZero())) &&
-		next != nil && next.Status == corev1.ConditionTrue && next.FirstTruthyTime != nil && !next.FirstTruthyTime.IsZero() &&
-		it.Status.InitializationTimestamp != nil {
+	next := it.Status.GetCondition(v1.IntegrationConditionReady)
+	if isIntegrationUpdated(it, previous, next) {
 		duration := next.FirstTruthyTime.Time.Sub(it.Status.InitializationTimestamp.Time)
 		Log.WithValues("request-namespace", it.Namespace, "request-name", it.Name, "ready-after", duration.Seconds()).
 			ForIntegration(it).Infof("First readiness after %s", duration)
@@ -108,6 +107,16 @@ func integrationUpdateFunc(old *v1.Integration, it *v1.Integration) bool {
 		old.Status.Phase != it.Status.Phase
 }
 
+func isIntegrationUpdated(it *v1.Integration, previous, next *v1.IntegrationCondition) bool {
+	if previous == nil || previous.Status != corev1.ConditionTrue && (previous.FirstTruthyTime == nil || previous.FirstTruthyTime.IsZero()) {
+		if next != nil && next.Status == corev1.ConditionTrue && next.FirstTruthyTime != nil && !next.FirstTruthyTime.IsZero() {
+			return it.Status.InitializationTimestamp != nil
+		}
+	}
+
+	return false
+}
+
 func integrationKitEnqueueRequestsFromMapFunc(c client.Client, kit *v1.IntegrationKit) []reconcile.Request {
 	var requests []reconcile.Request
 	if kit.Status.Phase != v1.IntegrationKitPhaseReady && kit.Status.Phase != v1.IntegrationKitPhaseError {


[camel-k] 02/07: feat(metadata): raise error when capability/dependency not resolved in CamelCatalog

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 1bb2a6c824a4fa63c195657f677d2db6df8cbeea
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Mon Sep 12 13:22:33 2022 +0900

    feat(metadata): raise error when capability/dependency not resolved in CamelCatalog
---
 addons/keda/keda_test.go                           |  49 ++++-----
 addons/resume/resume.go                            |   5 +-
 pkg/apis/camel/v1/camelcatalog_types_support.go    |  12 +++
 pkg/metadata/metadata_dependencies_test.go         | 109 +++++++++++---------
 pkg/metadata/metadata_http_test.go                 |  44 ++++----
 pkg/metadata/metadata_uri_test.go                  |  85 ++++++++--------
 pkg/trait/kamelets.go                              |   4 +-
 pkg/trait/kamelets_test.go                         |  41 ++++----
 pkg/trait/knative_service_test.go                  |  21 ++--
 pkg/trait/mount_test.go                            |   9 +-
 pkg/util/source/inspector.go                       | 112 +++++++++++++++------
 pkg/util/source/inspector_groovy.go                |  20 +---
 pkg/util/source/inspector_java_script.go           |  20 +---
 pkg/util/source/inspector_java_source.go           |  20 +---
 pkg/util/source/inspector_kotlin.go                |  20 +---
 pkg/util/source/inspector_xml.go                   |  14 ++-
 pkg/util/source/inspector_yaml.go                  |  16 +--
 .../source/{inspector_kamelet.go => kamelet.go}    |   0
 pkg/util/source/types.go                           |  16 ++-
 19 files changed, 321 insertions(+), 296 deletions(-)

diff --git a/addons/keda/keda_test.go b/addons/keda/keda_test.go
index 4783653ca..75924a83d 100644
--- a/addons/keda/keda_test.go
+++ b/addons/keda/keda_test.go
@@ -35,17 +35,13 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
-)
-
-var (
-	testingTrue  = true
-	testingFalse = false
+	"k8s.io/utils/pointer"
 )
 
 func TestManualConfig(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
-	keda.Auto = &testingFalse
+	keda.Enabled = pointer.Bool(true)
+	keda.Auto = pointer.Bool(false)
 	meta := map[string]string{
 		"prop":      "val",
 		"camelCase": "VAL",
@@ -72,8 +68,8 @@ func TestManualConfig(t *testing.T) {
 
 func TestConfigFromSecret(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
-	keda.Auto = &testingFalse
+	keda.Enabled = pointer.Bool(true)
+	keda.Auto = pointer.Bool(false)
 	meta := map[string]string{
 		"prop":      "val",
 		"camelCase": "VAL",
@@ -119,7 +115,7 @@ func TestConfigFromSecret(t *testing.T) {
 
 func TestKameletAutoDetection(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
+	keda.Enabled = pointer.Bool(true)
 	env := createBasicTestEnvironment(
 		&camelv1alpha1.Kamelet{
 			ObjectMeta: metav1.ObjectMeta{
@@ -209,7 +205,7 @@ func TestKameletAutoDetection(t *testing.T) {
 
 func TestKameletBindingAutoDetection(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
+	keda.Enabled = pointer.Bool(true)
 	logEndpoint := "log:info"
 	klb := camelv1alpha1.KameletBinding{
 		ObjectMeta: metav1.ObjectMeta{
@@ -322,15 +318,15 @@ func TestKameletBindingAutoDetection(t *testing.T) {
 
 func TestHackReplicas(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
-	keda.Auto = &testingFalse
+	keda.Enabled = pointer.Bool(true)
+	keda.Auto = pointer.Bool(false)
 	keda.Triggers = append(keda.Triggers, kedaTrigger{
 		Type: "custom",
 		Metadata: map[string]string{
 			"a": "b",
 		},
 	})
-	keda.HackControllerReplicas = &testingTrue
+	keda.HackControllerReplicas = pointer.Bool(true)
 	env := createBasicTestEnvironment(
 		&camelv1.Integration{
 			ObjectMeta: metav1.ObjectMeta{
@@ -356,15 +352,15 @@ func TestHackReplicas(t *testing.T) {
 
 func TestHackKLBReplicas(t *testing.T) {
 	keda, _ := NewKedaTrait().(*kedaTrait)
-	keda.Enabled = &testingTrue
-	keda.Auto = &testingFalse
+	keda.Enabled = pointer.Bool(true)
+	keda.Auto = pointer.Bool(false)
 	keda.Triggers = append(keda.Triggers, kedaTrigger{
 		Type: "custom",
 		Metadata: map[string]string{
 			"a": "b",
 		},
 	})
-	keda.HackControllerReplicas = &testingTrue
+	keda.HackControllerReplicas = pointer.Bool(true)
 	env := createBasicTestEnvironment(
 		&camelv1alpha1.KameletBinding{
 			ObjectMeta: metav1.ObjectMeta{
@@ -483,19 +479,14 @@ func createBasicTestEnvironment(resources ...runtime.Object) *trait.Environment
 		}
 	}
 
+	camelCatalog, _ := camel.DefaultCatalog()
+
 	return &trait.Environment{
-		Catalog:     trait.NewCatalog(nil),
-		Ctx:         context.Background(),
-		Client:      fakeClient,
-		Integration: it,
-		CamelCatalog: &camel.RuntimeCatalog{
-			CamelCatalogSpec: camelv1.CamelCatalogSpec{
-				Runtime: camelv1.RuntimeSpec{
-					Version:  "0.0.1",
-					Provider: camelv1.RuntimeProviderQuarkus,
-				},
-			},
-		},
+		Catalog:               trait.NewCatalog(nil),
+		Ctx:                   context.Background(),
+		Client:                fakeClient,
+		Integration:           it,
+		CamelCatalog:          camelCatalog,
 		Platform:              pl,
 		Resources:             kubernetes.NewCollection(),
 		ApplicationProperties: make(map[string]string),
diff --git a/addons/resume/resume.go b/addons/resume/resume.go
index de590aa65..020c770e5 100644
--- a/addons/resume/resume.go
+++ b/addons/resume/resume.go
@@ -91,7 +91,10 @@ func (r *resumeTrait) Configure(environment *trait.Environment) (bool, error) {
 			return false, err
 		}
 
-		meta := metadata.ExtractAll(environment.CamelCatalog, sources)
+		meta, err := metadata.ExtractAll(environment.CamelCatalog, sources)
+		if err != nil {
+			return false, err
+		}
 
 		for _, endpoint := range meta.FromURIs {
 			log.Infof("Processing component %s", endpoint)
diff --git a/pkg/apis/camel/v1/camelcatalog_types_support.go b/pkg/apis/camel/v1/camelcatalog_types_support.go
index 9c0ba615b..0d643bdfb 100644
--- a/pkg/apis/camel/v1/camelcatalog_types_support.go
+++ b/pkg/apis/camel/v1/camelcatalog_types_support.go
@@ -62,6 +62,18 @@ func NewCamelCatalogList() CamelCatalogList {
 	}
 }
 
+// GetRuntimeVersion returns the Camel K runtime version of the catalog.
+func (c *CamelCatalogSpec) GetRuntimeVersion() string {
+	return c.Runtime.Version
+}
+
+// HasCapability checks if the given capability is present in the catalog.
+func (c *CamelCatalogSpec) HasCapability(capability string) bool {
+	_, ok := c.Runtime.Capabilities[capability]
+
+	return ok
+}
+
 // GetDependencyID returns a Camel K recognizable maven dependency for the artifact
 func (in *CamelArtifact) GetDependencyID() string {
 	switch {
diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go
index 61593de53..674cebdd4 100644
--- a/pkg/metadata/metadata_dependencies_test.go
+++ b/pkg/metadata/metadata_dependencies_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/util/camel"
@@ -35,7 +36,6 @@ func TestDependenciesJavaSource(t *testing.T) {
 
 			    from("telegram:bots/cippa").to("log:stash");
 			    from("timer:tick").to("amqp:queue");
-			    from("ine:xistent").to("amqp:queue");
 				from("twitter-search:{{twitterKeywords}}"
                     + "?delay={{twitterDelayMs}}");
 			`,
@@ -44,10 +44,10 @@ func TestDependenciesJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -71,7 +71,6 @@ func TestDependenciesJavaScript(t *testing.T) {
 
 			    from('telegram:bots/cippa').to("log:stash");
 			    from('timer:tick').to("amqp:queue");
-			    from("ine:xistent").to("amqp:queue");
 			    '"'
 		    `,
 		},
@@ -79,10 +78,10 @@ func TestDependenciesJavaScript(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -105,7 +104,6 @@ func TestDependenciesGroovy(t *testing.T) {
 
 			    from('telegram:bots/cippa').to("log:stash");
 			    from('timer:tick').to("amqp:queue");
-			    from("ine:xistent").to("amqp:queue");
 				from('twitter-search:{{twitterKeywords}}'
                     + '?delay={{twitterDelayMs}}');
 			    '"
@@ -115,10 +113,10 @@ func TestDependenciesGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -147,10 +145,10 @@ func TestDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -162,6 +160,27 @@ func TestDependencies(t *testing.T) {
 		meta.Dependencies.List())
 }
 
+func TestDependencyInexistent(t *testing.T) {
+	code := v1.SourceSpec{
+		DataSpec: v1.DataSpec{
+			Name: "Request.java",
+			Content: `
+			    from("http:test").to("log:end");
+			    from("https:test").to("log:end");
+			    from("twitter-timeline:test").to("mock:end");
+			    from("ine:xistent").to("amqp:queue");
+		    `,
+		},
+		Language: v1.LanguageJavaSource,
+	}
+
+	catalog, err := camel.DefaultCatalog()
+	require.NoError(t, err)
+
+	_, err = Extract(catalog, code)
+	assert.Error(t, err)
+}
+
 func TestDependenciesQuarkus(t *testing.T) {
 	code := v1.SourceSpec{
 		DataSpec: v1.DataSpec{
@@ -180,11 +199,11 @@ func TestDependenciesQuarkus(t *testing.T) {
 	}
 
 	catalog, err := camel.QuarkusCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.NotNil(t, catalog)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -212,10 +231,10 @@ func TestJacksonDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -241,10 +260,10 @@ func TestJacksonImplicitDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -276,10 +295,10 @@ func TestLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -311,10 +330,10 @@ func TestLanguageDependenciesTransformExpression(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -342,10 +361,10 @@ func TestCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -373,10 +392,10 @@ func TestRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -406,10 +425,10 @@ func TestRestWithPathDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -437,10 +456,10 @@ func TestRestConfigurationDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -467,10 +486,10 @@ func TestRestClosureDependencyGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -498,10 +517,10 @@ func TestRestClosureDependencyKotlin(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -533,10 +552,10 @@ func TestXMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -573,10 +592,10 @@ func TestXMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -631,10 +650,10 @@ func TestXMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -702,10 +721,10 @@ func TestYAMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -729,10 +748,10 @@ func TestYAMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -753,10 +772,10 @@ func TestYAMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
diff --git a/pkg/metadata/metadata_http_test.go b/pkg/metadata/metadata_http_test.go
index 15ebacf65..6aecde9fe 100644
--- a/pkg/metadata/metadata_http_test.go
+++ b/pkg/metadata/metadata_http_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/util/camel"
@@ -33,17 +34,16 @@ func TestHttpJavaSource(t *testing.T) {
 			Content: `
 			from("telegram:bots/cippa").to("log:stash");
 			from("netty-http:uri").to("log:stash");
-			from("ine:xistent").to("log:stash");
 		`,
 		},
 		Language: v1.LanguageJavaSource,
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -65,10 +65,10 @@ func TestHttpOnlyJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -87,10 +87,10 @@ func TestHttpOnlyJavaSourceRest(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -109,10 +109,10 @@ func TestHttpOnlyJavaSourceRest2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -124,7 +124,7 @@ func TestNoHttpGroovySource(t *testing.T) {
 			Name: "Request.groovy",
 			Content: `
 			from('direct:bots/cippa').to("log:stash");
-			from('teelgram:uri').to("log:stash");
+			from('telegram:uri').to("log:stash");
 			from('seda:path').to("log:stash");
 		`,
 		},
@@ -132,10 +132,10 @@ func TestNoHttpGroovySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.False(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -155,10 +155,10 @@ func TestHttpOnlyGroovySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -178,10 +178,10 @@ func TestHttpXMLSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -202,10 +202,10 @@ func TestHttpOnlyXMLSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := Extract(catalog, code)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -237,10 +237,10 @@ func TestMultilangHTTPOnlySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := ExtractAll(catalog, codes)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -274,10 +274,10 @@ func TestMultilangHTTPSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	meta, err := ExtractAll(catalog, codes)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
diff --git a/pkg/metadata/metadata_uri_test.go b/pkg/metadata/metadata_uri_test.go
index e046b4827..c22aa7b4a 100644
--- a/pkg/metadata/metadata_uri_test.go
+++ b/pkg/metadata/metadata_uri_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/util/camel"
@@ -47,10 +48,10 @@ func TestJava1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -75,8 +76,8 @@ func TestJava2(t *testing.T) {
 											"log:info?skipBodyLineSeparator=false"
 
 							               )
-							.toD("uri:2")
-							.toF("uri:%s", "3");
+							.toD("direct:2")
+							.toF("direct:%s", "3");
   				}
 			}
 		`,
@@ -85,16 +86,16 @@ func TestJava2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Len(t, metadata.FromURIs, 1)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
-	assert.Contains(t, metadata.ToURIs, "uri:2")
-	assert.Contains(t, metadata.ToURIs, "uri:%s") // resolution not supported yet
+	assert.Contains(t, metadata.ToURIs, "direct:2")
+	assert.Contains(t, metadata.ToURIs, "direct:%s") // resolution not supported yet
 	assert.Len(t, metadata.ToURIs, 3)
 }
 
@@ -109,26 +110,26 @@ func TestGroovy1(t *testing.T) {
 				.to   ('log:info?skipBodyLineSeparator=false').to(
 											'http://url' )
 
-			from("uri:2")
+			from("direct:2")
 		    	.setBody().constant("aa")
-				.to('uri:3')
+				.to('direct:3')
 		`,
 		},
 		Language: v1.LanguageGroovy,
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
-	assert.Contains(t, metadata.FromURIs, "uri:2")
+	assert.Contains(t, metadata.FromURIs, "direct:2")
 	assert.Len(t, metadata.FromURIs, 2)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
 	assert.Contains(t, metadata.ToURIs, "http://url")
-	assert.Contains(t, metadata.ToURIs, "uri:3")
+	assert.Contains(t, metadata.ToURIs, "direct:3")
 	assert.Len(t, metadata.ToURIs, 3)
 }
 
@@ -139,27 +140,27 @@ func TestGroovy2(t *testing.T) {
 			Content: `
 			rest().get("/")
 				.to   ('log:info?skipBodyLineSeparator=false').to( 'http://url' )
-						.toD('dyn:1')
+						.toD('seda:1')
 						.tony('thisisnot:anuri')
-						.toD( "dyn:2")
-						.toF( "f:%s", "2")
+						.toD( "seda:2")
+						.toF( "file:%s", "2")
 		`,
 		},
 		Language: v1.LanguageGroovy,
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Empty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
 	assert.Contains(t, metadata.ToURIs, "http://url")
-	assert.Contains(t, metadata.ToURIs, "dyn:1")
-	assert.Contains(t, metadata.ToURIs, "dyn:2")
-	assert.Contains(t, metadata.ToURIs, "f:%s") // resolution not supported yet
+	assert.Contains(t, metadata.ToURIs, "seda:1")
+	assert.Contains(t, metadata.ToURIs, "seda:2")
+	assert.Contains(t, metadata.ToURIs, "file:%s") // resolution not supported yet
 	assert.Len(t, metadata.ToURIs, 5)
 }
 
@@ -185,10 +186,10 @@ func TestXml1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:hello?period=3000")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -209,30 +210,30 @@ func TestKotlin1(t *testing.T) {
 				.to   ("log:info?skipBodyLineSeparator=false").to(
 											"http://url" )
 
-			from("uri:2")
+			from("direct:2")
 		    	.setBody().constant("aa")
-				.to("uri:3")
-				.toD("uri:4")
-				.toF("uri:%s", 5)
+				.to("direct:3")
+				.toD("direct:4")
+				.toF("direct:%s", 5)
 		`,
 		},
 		Language: v1.LanguageKotlin,
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
-	assert.Contains(t, metadata.FromURIs, "uri:2")
+	assert.Contains(t, metadata.FromURIs, "direct:2")
 	assert.Len(t, metadata.FromURIs, 2)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
 	assert.Contains(t, metadata.ToURIs, "http://url")
-	assert.Contains(t, metadata.ToURIs, "uri:3")
-	assert.Contains(t, metadata.ToURIs, "uri:4")
-	assert.Contains(t, metadata.ToURIs, "uri:%s") // resolution not supported yet
+	assert.Contains(t, metadata.ToURIs, "direct:3")
+	assert.Contains(t, metadata.ToURIs, "direct:4")
+	assert.Contains(t, metadata.ToURIs, "direct:%s") // resolution not supported yet
 	assert.Len(t, metadata.ToURIs, 5)
 }
 
@@ -244,24 +245,24 @@ func TestJavascript1(t *testing.T) {
 
 			rest().get("/")
 				.to   ('log:info?skipBodyLineSeparator=false').to( 'http://url' )
-				.toD("uri:2")
-				.toF("uri:%s", "3")
+				.toD("direct:2")
+				.toF("direct:%s", "3")
 		`,
 		},
 		Language: v1.LanguageJavaScript,
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.Empty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
 	assert.Contains(t, metadata.ToURIs, "http://url")
-	assert.Contains(t, metadata.ToURIs, "uri:2")
-	assert.Contains(t, metadata.ToURIs, "uri:%s") // resolution not supported yet
+	assert.Contains(t, metadata.ToURIs, "direct:2")
+	assert.Contains(t, metadata.ToURIs, "direct:%s") // resolution not supported yet
 	assert.Len(t, metadata.ToURIs, 4)
 }
 
@@ -289,10 +290,10 @@ func TestJYaml(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	metadata, err := Extract(catalog, source)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	assert.NotEmpty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index e71f78864..d7bafcc56 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -147,7 +147,7 @@ func (t *kameletsTrait) collectKamelets(e *Environment) (map[string]*v1alpha1.Ka
 	sort.Strings(missingKamelets)
 
 	if len(missingKamelets) > 0 {
-		message := fmt.Sprintf("kamelets %s found, %s not found in repositories: %s",
+		message := fmt.Sprintf("kamelets [%s] found, [%s] not found in repositories: %s",
 			strings.Join(availableKamelets, ","),
 			strings.Join(missingKamelets, ","),
 			repo.String())
@@ -166,7 +166,7 @@ func (t *kameletsTrait) collectKamelets(e *Environment) (map[string]*v1alpha1.Ka
 		v1.IntegrationConditionKameletsAvailable,
 		corev1.ConditionTrue,
 		v1.IntegrationConditionKameletsAvailableReason,
-		fmt.Sprintf("kamelets %s found in repositories: %s", strings.Join(availableKamelets, ","), repo.String()),
+		fmt.Sprintf("kamelets [%s] found in repositories: %s", strings.Join(availableKamelets, ","), repo.String()),
 	)
 
 	return kamelets, nil
diff --git a/pkg/trait/kamelets_test.go b/pkg/trait/kamelets_test.go
index 9a7737bd6..906fb6498 100644
--- a/pkg/trait/kamelets_test.go
+++ b/pkg/trait/kamelets_test.go
@@ -27,6 +27,7 @@ import (
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/test"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -40,7 +41,7 @@ func TestConfigurationNoKameletsUsed(t *testing.T) {
     - to: log:info
 `)
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.False(t, enabled)
 	assert.Equal(t, "", trait.List)
 }
@@ -60,7 +61,7 @@ func TestConfigurationWithKamelets(t *testing.T) {
     - to: kamelet://complex-.-.-1c/b
 `)
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"c0", "c1", "c2", "complex-.-.-1a", "complex-.-.-1b", "complex-.-.-1c"}, trait.getKameletKeys())
 	assert.Equal(t, []configurationKey{
@@ -100,12 +101,12 @@ func TestKameletLookup(t *testing.T) {
 		Status: v1alpha1.KameletStatus{Phase: v1alpha1.KameletPhaseReady},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"timer"}, trait.getKameletKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	cm := environment.Resources.GetConfigMap(func(_ *corev1.ConfigMap) bool { return true })
 	assert.NotNil(t, cm)
 	assert.Equal(t, "it-kamelet-timer-template", cm.Name)
@@ -149,12 +150,12 @@ func TestKameletSecondarySourcesLookup(t *testing.T) {
 		Status: v1alpha1.KameletStatus{Phase: v1alpha1.KameletPhaseReady},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"timer"}, trait.getKameletKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-template" })
 	assert.NotNil(t, cmFlow)
 	cmRes := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-000" })
@@ -200,12 +201,12 @@ func TestNonYAMLKameletLookup(t *testing.T) {
 		Status: v1alpha1.KameletStatus{Phase: v1alpha1.KameletPhaseReady},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"timer"}, trait.getKameletKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	cm := environment.Resources.GetConfigMap(func(_ *corev1.ConfigMap) bool { return true })
 	assert.NotNil(t, cm)
 	assert.Equal(t, "it-kamelet-timer-000", cm.Name)
@@ -276,12 +277,12 @@ func TestMultipleKamelets(t *testing.T) {
 		Status: v1alpha1.KameletStatus{Phase: v1alpha1.KameletPhaseReady},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"logger", "timer"}, trait.getKameletKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 
 	cmFlow := environment.Resources.GetConfigMap(func(c *corev1.ConfigMap) bool { return c.Name == "it-kamelet-timer-template" })
 	assert.NotNil(t, cmFlow)
@@ -363,13 +364,13 @@ func TestKameletConfigLookup(t *testing.T) {
 		},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"timer"}, trait.getKameletKeys())
 	assert.Equal(t, []configurationKey{newConfigurationKey("timer", "")}, trait.getConfigurationKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.Len(t, environment.Integration.Status.Configuration, 2)
 	assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret"})
 	assert.NotContains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret2"})
@@ -427,7 +428,7 @@ func TestKameletNamedConfigLookup(t *testing.T) {
 		},
 	})
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 	assert.Equal(t, []string{"timer"}, trait.getKameletKeys())
 	assert.Equal(t, []configurationKey{
@@ -436,7 +437,7 @@ func TestKameletNamedConfigLookup(t *testing.T) {
 	}, trait.getConfigurationKeys())
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.Len(t, environment.Integration.Status.Configuration, 2)
 	assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret"})
 	assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret2"})
@@ -468,7 +469,7 @@ func TestKameletConditionFalse(t *testing.T) {
 		})
 
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 
 	err = trait.Apply(environment)
@@ -478,8 +479,8 @@ func TestKameletConditionFalse(t *testing.T) {
 	cond := environment.Integration.Status.GetCondition(v1.IntegrationConditionKameletsAvailable)
 	assert.Equal(t, corev1.ConditionFalse, cond.Status)
 	assert.Equal(t, v1.IntegrationConditionKameletsAvailableReason, cond.Reason)
-	assert.Contains(t, cond.Message, "timer found")
-	assert.Contains(t, cond.Message, "none not found")
+	assert.Contains(t, cond.Message, "[timer] found")
+	assert.Contains(t, cond.Message, "[none] not found")
 }
 
 func TestKameletConditionTrue(t *testing.T) {
@@ -521,17 +522,17 @@ func TestKameletConditionTrue(t *testing.T) {
 		})
 
 	enabled, err := trait.Configure(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.True(t, enabled)
 
 	err = trait.Apply(environment)
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	assert.Len(t, environment.Integration.Status.Conditions, 1)
 
 	cond := environment.Integration.Status.GetCondition(v1.IntegrationConditionKameletsAvailable)
 	assert.Equal(t, corev1.ConditionTrue, cond.Status)
 	assert.Equal(t, v1.IntegrationConditionKameletsAvailableReason, cond.Reason)
-	assert.Contains(t, cond.Message, "none,timer found")
+	assert.Contains(t, cond.Message, "[none,timer] found")
 }
 
 func createKameletsTestEnvironment(flow string, objects ...runtime.Object) (*kameletsTrait, *Environment) {
diff --git a/pkg/trait/knative_service_test.go b/pkg/trait/knative_service_test.go
index 15f69a1aa..4719beaa2 100644
--- a/pkg/trait/knative_service_test.go
+++ b/pkg/trait/knative_service_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,12 +45,12 @@ const (
 
 func TestKnativeService(t *testing.T) {
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
 	traitCatalog := NewCatalog(nil)
 
-	compressedRoute, err := gzip.CompressBase64([]byte(`from("undertow:test").log("hello")`))
-	assert.NoError(t, err)
+	compressedRoute, err := gzip.CompressBase64([]byte(`from("platform-http:test").log("hello")`))
+	require.NoError(t, err)
 
 	environment := Environment{
 		CamelCatalog: catalog,
@@ -124,7 +125,7 @@ func TestKnativeService(t *testing.T) {
 
 	err = traitCatalog.apply(&environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("knative"))
 	assert.NotNil(t, envvar.Get(environment.EnvVars, "CAMEL_KNATIVE_CONFIGURATION"))
@@ -191,7 +192,7 @@ func TestKnativeService(t *testing.T) {
 
 func TestKnativeServiceWithCustomContainerName(t *testing.T) {
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
 	traitCatalog := NewCatalog(nil)
 
@@ -251,7 +252,7 @@ func TestKnativeServiceWithCustomContainerName(t *testing.T) {
 
 	err = traitCatalog.apply(&environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("knative-service"))
 	assert.NotNil(t, environment.GetTrait("container"))
@@ -272,7 +273,7 @@ func TestKnativeServiceWithCustomContainerName(t *testing.T) {
 
 func TestKnativeServiceWithResr(t *testing.T) {
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
 	traitCatalog := NewCatalog(nil)
 
@@ -333,7 +334,7 @@ func TestKnativeServiceWithResr(t *testing.T) {
 
 	err = traitCatalog.apply(&environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("knative"))
 
@@ -374,7 +375,7 @@ func createKnativeServiceTestEnvironment(t *testing.T, trait *traitv1.KnativeSer
 	t.Helper()
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
 	traitCatalog := NewCatalog(nil)
 
@@ -437,7 +438,7 @@ func createKnativeServiceTestEnvironment(t *testing.T, trait *traitv1.KnativeSer
 
 	err = traitCatalog.apply(environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
 	return environment
 }
diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go
index 5daa8db32..1e3953c22 100644
--- a/pkg/trait/mount_test.go
+++ b/pkg/trait/mount_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -44,7 +45,7 @@ func TestMountVolumesEmpty(t *testing.T) {
 
 	err := traitCatalog.apply(environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("mount"))
 
@@ -66,7 +67,7 @@ func TestMountVolumesIntegrationPhaseDeploying(t *testing.T) {
 
 	err := traitCatalog.apply(environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.NotNil(t, environment.GetTrait("mount"))
 
@@ -114,7 +115,7 @@ func TestMountVolumesIntegrationPhaseInitialization(t *testing.T) {
 
 	err := traitCatalog.apply(environment)
 
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotEmpty(t, environment.ExecutedTraits)
 	assert.Nil(t, environment.GetTrait("mount"))
 
@@ -128,7 +129,7 @@ func getNominalEnv(t *testing.T, traitCatalog *Catalog) *Environment {
 	t.Helper()
 	fakeClient, _ := test.NewFakeClient()
 	catalog, _ := camel.DefaultCatalog()
-	compressedRoute, _ := gzip.CompressBase64([]byte(`from("undertow:test").log("hello")`))
+	compressedRoute, _ := gzip.CompressBase64([]byte(`from("platform-http:test").log("hello")`))
 
 	return &Environment{
 		CamelCatalog: catalog,
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index be2b86ddc..b8334bae6 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -18,6 +18,7 @@ limitations under the License.
 package source
 
 import (
+	"fmt"
 	"regexp"
 	"strings"
 
@@ -161,12 +162,13 @@ var (
 	}
 )
 
-// Inspector --.
+// Inspector is the common interface for language specific inspector implementations.
 type Inspector interface {
 	Extract(v1.SourceSpec, *Metadata) error
 }
 
-// InspectorForLanguage --.
+// InspectorForLanguage is the factory function to return a new inspector for the given language
+// with the catalog.
 func InspectorForLanguage(catalog *camel.RuntimeCatalog, language v1.Language) Inspector {
 	switch language {
 	case v1.LanguageJavaSource:
@@ -217,13 +219,40 @@ func (i baseInspector) Extract(v1.SourceSpec, *Metadata) error {
 	return nil
 }
 
-// discoverDependencies returns a list of dependencies required by the given source code.
-func (i *baseInspector) discoverCapabilities(source v1.SourceSpec, meta *Metadata) {
+func (i *baseInspector) extract(source v1.SourceSpec, meta *Metadata,
+	from, to, kameletEips []string, hasRest bool) error {
+	meta.FromURIs = append(meta.FromURIs, from...)
+	meta.ToURIs = append(meta.ToURIs, to...)
+
+	for _, k := range kameletEips {
+		AddKamelet(meta, "kamelet:"+k)
+	}
+
+	if err := i.discoverCapabilities(source, meta); err != nil {
+		return err
+	}
+	if err := i.discoverDependencies(source, meta); err != nil {
+		return err
+	}
+	i.discoverKamelets(meta)
+
+	if hasRest {
+		meta.AddRequiredCapability(v1.CapabilityRest)
+	}
+
+	meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
+	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
+	return nil
+}
+
+// discoverCapabilities returns a list of dependencies required by the given source code.
+func (i *baseInspector) discoverCapabilities(source v1.SourceSpec, meta *Metadata) error {
 	uris := util.StringSliceJoin(meta.FromURIs, meta.ToURIs)
 
 	for _, uri := range uris {
 		if i.getURIPrefix(uri) == "platform-http" {
-			meta.RequiredCapabilities.Add(v1.CapabilityPlatformHTTP)
+			meta.AddRequiredCapability(v1.CapabilityPlatformHTTP)
 		}
 	}
 
@@ -233,34 +262,37 @@ func (i *baseInspector) discoverCapabilities(source v1.SourceSpec, meta *Metadat
 		}
 
 		for _, capability := range capabilities {
-			meta.RequiredCapabilities.Add(capability)
+			meta.AddRequiredCapability(capability)
 		}
 	}
+
+	// validate capabilities
+	var err error
+	meta.RequiredCapabilities.Each(func(capability string) bool {
+		if !i.catalog.HasCapability(capability) {
+			err = fmt.Errorf("capability %s not supported in camel catalog runtime version %s",
+				capability, i.catalog.GetRuntimeVersion())
+			return false
+		}
+		return true
+	})
+
+	return err
 }
 
 // discoverDependencies returns a list of dependencies required by the given source code.
-func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadata) {
+func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadata) error {
 	for _, uri := range meta.FromURIs {
-		candidateComp, scheme := i.catalog.DecodeComponent(uri)
-		if candidateComp != nil {
-			i.addDependency(candidateComp.GetDependencyID(), meta)
-			if scheme != nil {
-				for _, dep := range candidateComp.GetConsumerDependencyIDs(scheme.ID) {
-					i.addDependency(dep, meta)
-				}
-			}
+		// consumer
+		if err := i.addDependencies(uri, meta, true); err != nil {
+			return err
 		}
 	}
 
 	for _, uri := range meta.ToURIs {
-		candidateComp, scheme := i.catalog.DecodeComponent(uri)
-		if candidateComp != nil {
-			i.addDependency(candidateComp.GetDependencyID(), meta)
-			if scheme != nil {
-				for _, dep := range candidateComp.GetProducerDependencyIDs(scheme.ID) {
-					i.addDependency(dep, meta)
-				}
-			}
+		// producer
+		if err := i.addDependencies(uri, meta, false); err != nil {
+			return err
 		}
 	}
 
@@ -270,14 +302,14 @@ func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadat
 		}
 
 		for _, dep := range supplier(i.catalog) {
-			i.addDependency(dep, meta)
+			meta.AddDependency(dep)
 		}
 	}
 
 	for _, match := range languageRegexp.FindAllStringSubmatch(source.Content, -1) {
 		if len(match) > 1 {
 			if dependency, ok := i.catalog.GetLanguageDependency(match[1]); ok {
-				i.addDependency(dependency, meta)
+				meta.AddDependency(dependency)
 			}
 		}
 	}
@@ -285,15 +317,16 @@ func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadat
 	for _, match := range camelTypeRegexp.FindAllStringSubmatch(source.Content, -1) {
 		if len(match) > 1 {
 			if dependency, ok := i.catalog.GetJavaTypeDependency(match[1]); ok {
-				i.addDependency(dependency, meta)
+				meta.AddDependency(dependency)
 			}
 		}
 	}
+
+	return nil
 }
 
-// discoverDependencies inspects endpoints and extract kamelets
-// nolint: unparam
-func (i *baseInspector) discoverKamelets(source v1.SourceSpec, meta *Metadata) {
+// discoverKamelets inspects endpoints and extract kamelets.
+func (i *baseInspector) discoverKamelets(meta *Metadata) {
 	for _, uri := range meta.FromURIs {
 		AddKamelet(meta, uri)
 	}
@@ -302,8 +335,25 @@ func (i *baseInspector) discoverKamelets(source v1.SourceSpec, meta *Metadata) {
 	}
 }
 
-func (i *baseInspector) addDependency(dependency string, meta *Metadata) {
-	meta.Dependencies.Add(dependency)
+func (i *baseInspector) addDependencies(uri string, meta *Metadata, consumer bool) error {
+	candidateComp, scheme := i.catalog.DecodeComponent(uri)
+	if candidateComp == nil || scheme == nil {
+		return fmt.Errorf("component not found for uri %q in camel catalog runtime version %s",
+			uri, i.catalog.GetRuntimeVersion())
+	}
+
+	meta.AddDependency(candidateComp.GetDependencyID())
+	var deps []string
+	if consumer {
+		deps = candidateComp.GetConsumerDependencyIDs(scheme.ID)
+	} else {
+		deps = candidateComp.GetProducerDependencyIDs(scheme.ID)
+	}
+	for _, dep := range deps {
+		meta.AddDependency(dep)
+	}
+
+	return nil
 }
 
 // hasOnlyPassiveEndpoints returns true if the source has no endpoint that needs to remain always active.
diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go
index 686814084..210ee99b4 100644
--- a/pkg/util/source/inspector_groovy.go
+++ b/pkg/util/source/inspector_groovy.go
@@ -45,30 +45,12 @@ func (i GroovyInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 		singleQuotedWireTap,
 		doubleQuotedWireTap,
 	)
-
-	meta.FromURIs = append(meta.FromURIs, from...)
-	meta.ToURIs = append(meta.ToURIs, to...)
-
 	kameletEips := util.FindAllDistinctStringSubmatch(
 		source.Content,
 		singleQuotedKameletEip,
 		doubleQuotedKameletEip)
 
-	for _, k := range kameletEips {
-		AddKamelet(meta, "kamelet:"+k)
-	}
-
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
-
 	hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
-	if hasRest {
-		meta.RequiredCapabilities.Add(v1.CapabilityRest)
-	}
-
-	meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
-	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
 
-	return nil
+	return i.extract(source, meta, from, to, kameletEips, hasRest)
 }
diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go
index ebcbe37bb..d6d74c331 100644
--- a/pkg/util/source/inspector_java_script.go
+++ b/pkg/util/source/inspector_java_script.go
@@ -45,30 +45,12 @@ func (i JavaScriptInspector) Extract(source v1.SourceSpec, meta *Metadata) error
 		singleQuotedWireTap,
 		doubleQuotedWireTap,
 	)
-
-	meta.FromURIs = append(meta.FromURIs, from...)
-	meta.ToURIs = append(meta.ToURIs, to...)
-
 	kameletEips := util.FindAllDistinctStringSubmatch(
 		source.Content,
 		singleQuotedKameletEip,
 		doubleQuotedKameletEip)
 
-	for _, k := range kameletEips {
-		AddKamelet(meta, "kamelet:"+k)
-	}
-
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
-
 	hasRest := restRegexp.MatchString(source.Content)
-	if hasRest {
-		meta.RequiredCapabilities.Add(v1.CapabilityRest)
-	}
-
-	meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
-	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
 
-	return nil
+	return i.extract(source, meta, from, to, kameletEips, hasRest)
 }
diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go
index 00a9f391f..6fd6ee59d 100644
--- a/pkg/util/source/inspector_java_source.go
+++ b/pkg/util/source/inspector_java_source.go
@@ -39,30 +39,12 @@ func (i JavaSourceInspector) Extract(source v1.SourceSpec, meta *Metadata) error
 		doubleQuotedToF,
 		doubleQuotedWireTap,
 	)
-
-	meta.FromURIs = append(meta.FromURIs, from...)
-	meta.ToURIs = append(meta.ToURIs, to...)
-
 	kameletEips := util.FindAllDistinctStringSubmatch(
 		source.Content,
 		singleQuotedKameletEip,
 		doubleQuotedKameletEip)
 
-	for _, k := range kameletEips {
-		AddKamelet(meta, "kamelet:"+k)
-	}
-
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
-
 	hasRest := restRegexp.MatchString(source.Content)
-	if hasRest {
-		meta.RequiredCapabilities.Add(v1.CapabilityRest)
-	}
-
-	meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
-	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
 
-	return nil
+	return i.extract(source, meta, from, to, kameletEips, hasRest)
 }
diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go
index 753d0dbbf..e3f4a8d75 100644
--- a/pkg/util/source/inspector_kotlin.go
+++ b/pkg/util/source/inspector_kotlin.go
@@ -39,30 +39,12 @@ func (i KotlinInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 		doubleQuotedToF,
 		doubleQuotedWireTap,
 	)
-
-	meta.FromURIs = append(meta.FromURIs, from...)
-	meta.ToURIs = append(meta.ToURIs, to...)
-
 	kameletEips := util.FindAllDistinctStringSubmatch(
 		source.Content,
 		singleQuotedKameletEip,
 		doubleQuotedKameletEip)
 
-	for _, k := range kameletEips {
-		AddKamelet(meta, "kamelet:"+k)
-	}
-
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
-
 	hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
-	if hasRest {
-		meta.RequiredCapabilities.Add(v1.CapabilityRest)
-	}
-
-	meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
-	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
 
-	return nil
+	return i.extract(source, meta, from, to, kameletEips, hasRest)
 }
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index 51baaee24..3e55eb3b9 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -52,7 +52,7 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 				for _, a := range se.Attr {
 					if a.Name.Local == "language" {
 						if dependency, ok := i.catalog.GetLanguageDependency(a.Value); ok {
-							i.addDependency(dependency, meta)
+							meta.AddDependency(dependency)
 						}
 					}
 				}
@@ -77,14 +77,18 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 			}
 
 			if dependency, ok := i.catalog.GetLanguageDependency(se.Name.Local); ok {
-				i.addDependency(dependency, meta)
+				meta.AddDependency(dependency)
 			}
 		}
 	}
 
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
+	if err := i.discoverCapabilities(source, meta); err != nil {
+		return err
+	}
+	if err := i.discoverDependencies(source, meta); err != nil {
+		return err
+	}
+	i.discoverKamelets(meta)
 
 	meta.ExposesHTTPServices = meta.ExposesHTTPServices || i.containsHTTPURIs(meta.FromURIs)
 	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index a28ac260e..e672f763d 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -48,9 +48,13 @@ func (i YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 		}
 	}
 
-	i.discoverCapabilities(source, meta)
-	i.discoverDependencies(source, meta)
-	i.discoverKamelets(source, meta)
+	if err := i.discoverCapabilities(source, meta); err != nil {
+		return err
+	}
+	if err := i.discoverDependencies(source, meta); err != nil {
+		return err
+	}
+	i.discoverKamelets(meta)
 
 	meta.ExposesHTTPServices = meta.ExposesHTTPServices || i.containsHTTPURIs(meta.FromURIs)
 	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
@@ -77,7 +81,7 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata
 					}
 				}
 				if dfDep := i.catalog.GetArtifactByDataFormat(dataFormatID); dfDep != nil {
-					i.addDependency(dfDep.GetDependencyID(), meta)
+					meta.AddDependency(dfDep.GetDependencyID())
 				}
 			}
 		}
@@ -102,7 +106,7 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata
 
 			if s, ok := k.(string); ok {
 				if dependency, ok := i.catalog.GetLanguageDependency(s); ok {
-					i.addDependency(dependency, meta)
+					meta.AddDependency(dependency)
 				}
 			}
 
@@ -133,7 +137,7 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata
 			case "language":
 				if s, ok := v.(string); ok {
 					if dependency, ok := i.catalog.GetLanguageDependency(s); ok {
-						i.addDependency(dependency, meta)
+						meta.AddDependency(dependency)
 					}
 				} else if m, ok := v.(map[interface{}]interface{}); ok {
 					if err := i.parseStep("language", m, meta); err != nil {
diff --git a/pkg/util/source/inspector_kamelet.go b/pkg/util/source/kamelet.go
similarity index 100%
rename from pkg/util/source/inspector_kamelet.go
rename to pkg/util/source/kamelet.go
diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go
index 76ff78917..3c8304d63 100644
--- a/pkg/util/source/types.go
+++ b/pkg/util/source/types.go
@@ -17,9 +17,11 @@ limitations under the License.
 
 package source
 
-import "github.com/scylladb/go-set/strset"
+import (
+	"github.com/scylladb/go-set/strset"
+)
 
-// Metadata --.
+// Metadata represents metadata for Integration source.
 type Metadata struct {
 	// All starting URIs of defined routes
 	FromURIs []string
@@ -41,7 +43,7 @@ type Metadata struct {
 	Kamelets []string
 }
 
-// NewMetadata --.
+// NewMetadata creates a new metadata.
 func NewMetadata() Metadata {
 	return Metadata{
 		FromURIs:             make([]string, 0),
@@ -50,3 +52,11 @@ func NewMetadata() Metadata {
 		RequiredCapabilities: strset.New(),
 	}
 }
+
+func (m *Metadata) AddRequiredCapability(capability string) {
+	m.RequiredCapabilities.Add(capability)
+}
+
+func (m *Metadata) AddDependency(dependency string) {
+	m.Dependencies.Add(dependency)
+}


[camel-k] 07/07: fix(e2e): add E2E test for reconcilation of integrations in initialisation failed condition

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 151def156ef0bcb8f4b05e95a2eb7de75cf111fd
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Sep 13 18:05:28 2022 +0900

    fix(e2e): add E2E test for reconcilation of integrations in initialisation failed condition
---
 e2e/global/common/integration_fail_test.go | 7 +++++++
 e2e/global/common/operator_metrics_test.go | 5 +++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/e2e/global/common/integration_fail_test.go b/e2e/global/common/integration_fail_test.go
index 0f498ac84..cf999630c 100644
--- a/e2e/global/common/integration_fail_test.go
+++ b/e2e/global/common/integration_fail_test.go
@@ -96,6 +96,13 @@ func TestBadRouteIntegration(t *testing.T) {
 			// Kit shouldn't be created
 			Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
 
+			// Fixing the route should reconcile the Integration in Initialization Failed condition to Running
+			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
 			// Clean up
 			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 		})
diff --git a/e2e/global/common/operator_metrics_test.go b/e2e/global/common/operator_metrics_test.go
index c0c1e9ed5..db24f0f62 100644
--- a/e2e/global/common/operator_metrics_test.go
+++ b/e2e/global/common/operator_metrics_test.go
@@ -65,8 +65,9 @@ func TestMetrics(t *testing.T) {
 			"-t", "prometheus.pod-monitor=false",
 		).Execute()).To(Succeed())
 		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 
 		pod := OperatorPod(ns)()
 		Expect(pod).NotTo(BeNil())


[camel-k] 01/07: fix(metadata): add error handling on metadata extraction

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit f3d5764432b7983fc35487b5d0ff5324929a60e0
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Aug 23 14:34:26 2022 +0900

    fix(metadata): add error handling on metadata extraction
---
 addons/keda/keda.go                        |   6 +-
 addons/master/master.go                    |   5 +-
 pkg/cmd/local/local.go                     |   6 +-
 pkg/metadata/metadata.go                   |  31 ++++++---
 pkg/metadata/metadata_capabilities_test.go |   5 +-
 pkg/metadata/metadata_dependencies_test.go | 105 +++++++++++++++++------------
 pkg/metadata/metadata_http_test.go         |  50 ++++++++------
 pkg/metadata/metadata_uri_test.go          |  40 ++++++-----
 pkg/trait/cron.go                          |   6 +-
 pkg/trait/dependencies.go                  |  13 +++-
 pkg/trait/knative.go                       |  36 ++++++----
 pkg/trait/knative_service.go               |  10 ++-
 pkg/trait/service.go                       |   5 +-
 pkg/trait/util.go                          |  10 ++-
 pkg/util/kamelets/util.go                  |   7 +-
 15 files changed, 217 insertions(+), 118 deletions(-)

diff --git a/addons/keda/keda.go b/addons/keda/keda.go
index 26ded971b..1b5aa0ab4 100644
--- a/addons/keda/keda.go
+++ b/addons/keda/keda.go
@@ -318,7 +318,7 @@ func (t *kedaTrait) populateTriggersFromKamelets(e *trait.Environment) error {
 		return err
 	}
 	kameletURIs := make(map[string][]string)
-	metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+	if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 		for _, kameletURI := range meta.FromURIs {
 			if kameletStr := source.ExtractKamelet(kameletURI); kameletStr != "" && camelv1alpha1.ValidKameletName(kameletStr) {
 				kamelet := kameletStr
@@ -332,7 +332,9 @@ func (t *kedaTrait) populateTriggersFromKamelets(e *trait.Environment) error {
 			}
 		}
 		return true
-	})
+	}); err != nil {
+		return err
+	}
 
 	if len(kameletURIs) == 0 {
 		return nil
diff --git a/addons/master/master.go b/addons/master/master.go
index 5c79ffde2..80d7a36ba 100644
--- a/addons/master/master.go
+++ b/addons/master/master.go
@@ -100,7 +100,10 @@ func (t *masterTrait) Configure(e *trait.Environment) (bool, error) {
 			return false, err
 		}
 
-		meta := metadata.ExtractAll(e.CamelCatalog, sources)
+		meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+		if err != nil {
+			return false, err
+		}
 
 		if t.Enabled == nil {
 			for _, endpoint := range meta.FromURIs {
diff --git a/pkg/cmd/local/local.go b/pkg/cmd/local/local.go
index 8f150ad6c..9ba54dd66 100644
--- a/pkg/cmd/local/local.go
+++ b/pkg/cmd/local/local.go
@@ -100,7 +100,11 @@ func getTopLevelDependencies(ctx context.Context, catalog *camel.RuntimeCatalog,
 		}
 
 		// Extract list of top-level dependencies
-		dependencies.Merge(trait.AddSourceDependencies(sourceSpec, catalog))
+		srcDeps, err := trait.ExtractSourceDependencies(sourceSpec, catalog)
+		if err != nil {
+			return nil, err
+		}
+		dependencies.Merge(srcDeps)
 	}
 
 	return dependencies.List(), nil
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index 02ab8f838..d73c7b221 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -26,18 +26,23 @@ import (
 )
 
 // ExtractAll returns metadata information from all listed source codes.
-func ExtractAll(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec) IntegrationMetadata {
+func ExtractAll(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec) (IntegrationMetadata, error) {
 	// neutral metadata
 	meta := src.NewMetadata()
 	meta.PassiveEndpoints = true
 	meta.ExposesHTTPServices = false
 
 	for _, source := range sources {
-		meta = merge(meta, Extract(catalog, source).Metadata)
+		m, err := Extract(catalog, source)
+		if err != nil {
+			return IntegrationMetadata{}, err
+		}
+		meta = merge(meta, m.Metadata)
 	}
+
 	return IntegrationMetadata{
 		Metadata: meta,
-	}
+	}, nil
 }
 
 func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
@@ -60,7 +65,7 @@ func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
 }
 
 // Extract returns metadata information from the source code.
-func Extract(catalog *camel.RuntimeCatalog, source v1.SourceSpec) IntegrationMetadata {
+func Extract(catalog *camel.RuntimeCatalog, source v1.SourceSpec) (IntegrationMetadata, error) {
 	if source.ContentRef != "" {
 		panic("source must be dereferenced before calling this method")
 	}
@@ -74,21 +79,27 @@ func Extract(catalog *camel.RuntimeCatalog, source v1.SourceSpec) IntegrationMet
 	meta.PassiveEndpoints = true
 	meta.ExposesHTTPServices = false
 
-	// TODO: handle error
-	_ = src.InspectorForLanguage(catalog, language).Extract(source, &meta)
+	if err := src.InspectorForLanguage(catalog, language).Extract(source, &meta); err != nil {
+		return IntegrationMetadata{}, err
+	}
 
 	return IntegrationMetadata{
 		Metadata: meta,
-	}
+	}, nil
 }
 
-// Each --.
-func Each(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec, consumer func(int, IntegrationMetadata) bool) {
+// Each traverses the sources with the provided consumer function.
+func Each(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec, consumer func(int, IntegrationMetadata) bool) error {
 	for i, s := range sources {
-		meta := Extract(catalog, s)
+		meta, err := Extract(catalog, s)
+		if err != nil {
+			return err
+		}
 
 		if !consumer(i, meta) {
 			break
 		}
 	}
+
+	return nil
 }
diff --git a/pkg/metadata/metadata_capabilities_test.go b/pkg/metadata/metadata_capabilities_test.go
index 349e4850e..e283e9a6f 100644
--- a/pkg/metadata/metadata_capabilities_test.go
+++ b/pkg/metadata/metadata_capabilities_test.go
@@ -36,9 +36,10 @@ func TestPlatformHttpCapabilities(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go
index c3a014b94..61593de53 100644
--- a/pkg/metadata/metadata_dependencies_test.go
+++ b/pkg/metadata/metadata_dependencies_test.go
@@ -44,9 +44,10 @@ func TestDependenciesJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -78,9 +79,10 @@ func TestDependenciesJavaScript(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -113,9 +115,10 @@ func TestDependenciesGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -144,9 +147,10 @@ func TestDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -176,10 +180,11 @@ func TestDependenciesQuarkus(t *testing.T) {
 	}
 
 	catalog, err := camel.QuarkusCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 	assert.NotNil(t, catalog)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -207,9 +212,10 @@ func TestJacksonDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -235,9 +241,10 @@ func TestJacksonImplicitDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -269,9 +276,10 @@ func TestLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -303,9 +311,10 @@ func TestLanguageDependenciesTransformExpression(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -333,9 +342,10 @@ func TestCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -363,9 +373,10 @@ func TestRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -395,9 +406,10 @@ func TestRestWithPathDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -425,9 +437,10 @@ func TestRestConfigurationDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -454,9 +467,10 @@ func TestRestClosureDependencyGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -484,9 +498,10 @@ func TestRestClosureDependencyKotlin(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -518,9 +533,10 @@ func TestXMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -557,9 +573,10 @@ func TestXMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -614,9 +631,10 @@ func TestXMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -684,9 +702,10 @@ func TestYAMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -710,9 +729,10 @@ func TestYAMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -733,9 +753,10 @@ func TestYAMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
diff --git a/pkg/metadata/metadata_http_test.go b/pkg/metadata/metadata_http_test.go
index 3f653acdf..15ebacf65 100644
--- a/pkg/metadata/metadata_http_test.go
+++ b/pkg/metadata/metadata_http_test.go
@@ -40,9 +40,10 @@ func TestHttpJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -64,9 +65,10 @@ func TestHttpOnlyJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -85,9 +87,10 @@ func TestHttpOnlyJavaSourceRest(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -106,9 +109,10 @@ func TestHttpOnlyJavaSourceRest2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -128,9 +132,10 @@ func TestNoHttpGroovySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.False(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -150,9 +155,10 @@ func TestHttpOnlyGroovySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -172,9 +178,10 @@ func TestHttpXMLSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
@@ -195,9 +202,10 @@ func TestHttpOnlyXMLSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -229,9 +237,10 @@ func TestMultilangHTTPOnlySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := ExtractAll(catalog, codes)
+	meta, err := ExtractAll(catalog, codes)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -265,9 +274,10 @@ func TestMultilangHTTPSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	meta := ExtractAll(catalog, codes)
+	meta, err := ExtractAll(catalog, codes)
+	assert.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.False(t, meta.PassiveEndpoints)
diff --git a/pkg/metadata/metadata_uri_test.go b/pkg/metadata/metadata_uri_test.go
index 90d526e9e..e046b4827 100644
--- a/pkg/metadata/metadata_uri_test.go
+++ b/pkg/metadata/metadata_uri_test.go
@@ -47,9 +47,10 @@ func TestJava1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -84,9 +85,10 @@ func TestJava2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -116,9 +118,10 @@ func TestGroovy1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Contains(t, metadata.FromURIs, "uri:2")
@@ -146,9 +149,10 @@ func TestGroovy2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Empty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
@@ -181,9 +185,10 @@ func TestXml1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:hello?period=3000")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -215,9 +220,10 @@ func TestKotlin1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Contains(t, metadata.FromURIs, "uri:2")
@@ -246,9 +252,10 @@ func TestJavascript1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.Empty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.ToURIs, "log:info?skipBodyLineSeparator=false")
@@ -282,9 +289,10 @@ func TestJYaml(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	assert.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	assert.NoError(t, err)
 
 	assert.NotEmpty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go
index c39e8cbd4..7d28867bd 100644
--- a/pkg/trait/cron.go
+++ b/pkg/trait/cron.go
@@ -353,7 +353,11 @@ func (t *cronTrait) getSourcesFromURIs(e *Environment) ([]string, error) {
 	if sources, err = kubernetes.ResolveIntegrationSources(e.Ctx, t.Client, e.Integration, e.Resources); err != nil {
 		return nil, err
 	}
-	meta := metadata.ExtractAll(e.CamelCatalog, sources)
+	meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+	if err != nil {
+		return nil, err
+	}
+
 	return meta.FromURIs, nil
 }
 
diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go
index 440291c9a..5a68c3cef 100644
--- a/pkg/trait/dependencies.go
+++ b/pkg/trait/dependencies.go
@@ -70,9 +70,16 @@ func (t *dependenciesTrait) Apply(e *Environment) error {
 	}
 	for _, s := range sources {
 		// Add source-related dependencies
-		dependencies.Merge(AddSourceDependencies(s, e.CamelCatalog))
-
-		meta := metadata.Extract(e.CamelCatalog, s)
+		srcDeps, err := ExtractSourceDependencies(s, e.CamelCatalog)
+		if err != nil {
+			return err
+		}
+		dependencies.Merge(srcDeps)
+
+		meta, err := metadata.Extract(e.CamelCatalog, s)
+		if err != nil {
+			return err
+		}
 		meta.RequiredCapabilities.Each(func(item string) bool {
 			util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, item)
 			return true
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 935e0d03f..146f75506 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -84,10 +84,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.FromURIs, knativeapi.CamelServiceTypeChannel)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.ChannelSources = items
 		}
@@ -97,10 +99,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.ToURIs, knativeapi.CamelServiceTypeChannel)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.ChannelSinks = items
 		}
@@ -110,10 +114,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.FromURIs, knativeapi.CamelServiceTypeEndpoint)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.EndpointSources = items
 		}
@@ -123,10 +129,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.ToURIs, knativeapi.CamelServiceTypeEndpoint)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.EndpointSinks = items
 		}
@@ -136,10 +144,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.FromURIs, knativeapi.CamelServiceTypeEvent)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.EventSources = items
 		}
@@ -149,10 +159,12 @@ func (t *knativeTrait) Configure(e *Environment) (bool, error) {
 			if err != nil {
 				return false, err
 			}
-			metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+			if err := metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 				items = append(items, knativeutil.FilterURIs(meta.ToURIs, knativeapi.CamelServiceTypeEvent)...)
 				return true
-			})
+			}); err != nil {
+				return false, err
+			}
 
 			t.EventSinks = items
 		}
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 606aafd14..258e38bb5 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -132,7 +132,10 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 				return false, err
 			}
 
-			meta := metadata.ExtractAll(e.CamelCatalog, sources)
+			meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+			if err != nil {
+				return false, err
+			}
 			if !meta.ExposesHTTPServices || !meta.PassiveEndpoints {
 				single := 1
 				t.MinScale = &single
@@ -180,7 +183,10 @@ func (t *knativeServiceTrait) SelectControllerStrategy(e *Environment) (*Control
 		return nil, err
 	}
 
-	meta := metadata.ExtractAll(e.CamelCatalog, sources)
+	meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+	if err != nil {
+		return nil, err
+	}
 	if meta.ExposesHTTPServices {
 		return &knativeServiceStrategy, nil
 	}
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index eb46b5cb5..c707ce281 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -80,7 +80,10 @@ func (t *serviceTrait) Configure(e *Environment) (bool, error) {
 			return false, err
 		}
 
-		meta := metadata.ExtractAll(e.CamelCatalog, sources)
+		meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+		if err != nil {
+			return false, err
+		}
 		if !meta.ExposesHTTPServices {
 			e.Integration.Status.SetCondition(
 				v1.IntegrationConditionServiceAvailable,
diff --git a/pkg/trait/util.go b/pkg/trait/util.go
index ef9a5d323..69d9c3db2 100644
--- a/pkg/trait/util.go
+++ b/pkg/trait/util.go
@@ -211,11 +211,15 @@ func toHostDir(host string) string {
 	return toFileName.ReplaceAllString(h, "_")
 }
 
-func AddSourceDependencies(source v1.SourceSpec, catalog *camel.RuntimeCatalog) *strset.Set {
+// ExtractSourceDependencies extracts dependencies from source.
+func ExtractSourceDependencies(source v1.SourceSpec, catalog *camel.RuntimeCatalog) (*strset.Set, error) {
 	dependencies := strset.New()
 
 	// Add auto-detected dependencies
-	meta := metadata.Extract(catalog, source)
+	meta, err := metadata.Extract(catalog, source)
+	if err != nil {
+		return nil, err
+	}
 	dependencies.Merge(meta.Dependencies)
 
 	// Add loader dependencies
@@ -240,7 +244,7 @@ func AddSourceDependencies(source v1.SourceSpec, catalog *camel.RuntimeCatalog)
 		}
 	}
 
-	return dependencies
+	return dependencies, nil
 }
 
 // AssertTraitsType asserts that traits is either v1.Traits or v1.IntegrationKitTraits.
diff --git a/pkg/util/kamelets/util.go b/pkg/util/kamelets/util.go
index 2db03c7fc..c849ce729 100644
--- a/pkg/util/kamelets/util.go
+++ b/pkg/util/kamelets/util.go
@@ -39,10 +39,13 @@ func ExtractKameletFromSources(context context.Context, c client.Client, catalog
 	if err != nil {
 		return nil, err
 	}
-	metadata.Each(catalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
+
+	if err := metadata.Each(catalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool {
 		util.StringSliceUniqueConcat(&kamelets, meta.Kamelets)
 		return true
-	})
+	}); err != nil {
+		return nil, err
+	}
 
 	// Check if a Kamelet is configured as default error handler URI
 	defaultErrorHandlerURI := it.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerAppPropertiesPrefix + ".deadLetterUri")


[camel-k] 03/07: fix(trait): traits for Initialization phase should not trigger at platform setup action

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 28550fcac6c57a954ccc3c558d2c4590d5af168e
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Sep 13 13:45:20 2022 +0900

    fix(trait): traits for Initialization phase should not trigger at platform setup action
---
 pkg/apis/camel/v1/integration_types.go       |  4 +-
 pkg/controller/integration/platform_setup.go |  7 +++
 pkg/trait/platform.go                        | 94 +++++++++++++++-------------
 pkg/trait/platform_test.go                   |  2 +-
 4 files changed, 62 insertions(+), 45 deletions(-)

diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 3ba0c2768..c6f1e750e 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -148,10 +148,10 @@ const (
 
 	// IntegrationPhaseNone --
 	IntegrationPhaseNone IntegrationPhase = ""
-	// IntegrationPhaseInitialization --
-	IntegrationPhaseInitialization IntegrationPhase = "Initialization"
 	// IntegrationPhaseWaitingForPlatform --
 	IntegrationPhaseWaitingForPlatform IntegrationPhase = "Waiting For Platform"
+	// IntegrationPhaseInitialization --
+	IntegrationPhaseInitialization IntegrationPhase = "Initialization"
 	// IntegrationPhaseBuildingKit --
 	IntegrationPhaseBuildingKit IntegrationPhase = "Building Kit"
 	// IntegrationPhaseDeploying --
diff --git a/pkg/controller/integration/platform_setup.go b/pkg/controller/integration/platform_setup.go
index 148673ec2..6c1b85bb1 100644
--- a/pkg/controller/integration/platform_setup.go
+++ b/pkg/controller/integration/platform_setup.go
@@ -62,6 +62,13 @@ func (action *platformSetupAction) Handle(ctx context.Context, integration *v1.I
 		integration.Status.Profile = determineBestProfile(ctx, action.client, integration, pl)
 	}
 
+	// Change the integration phase to Initialization after traits have been applied
+	// so that traits targeting Initialization phase don't get applied unintentionally
+	// at the platform setup step.
+	if integration.Status.Phase != v1.IntegrationPhaseWaitingForPlatform {
+		integration.Status.Phase = v1.IntegrationPhaseInitialization
+	}
+
 	return integration, nil
 }
 
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index d2e7b6783..b6ed793cd 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -80,20 +80,31 @@ func (t *platformTrait) Apply(e *Environment) error {
 	initial := e.Integration.DeepCopy()
 
 	pl, err := t.getOrCreatePlatform(e)
-	if err != nil || pl.Status.Phase != v1.IntegrationPlatformPhaseReady {
+	// Do not change to Initialization phase within the trait
+	switch {
+	case err != nil:
 		e.Integration.Status.Phase = v1.IntegrationPhaseWaitingForPlatform
-	} else {
-		e.Integration.Status.Phase = v1.IntegrationPhaseInitialization
-	}
-
-	if initial.Status.Phase != e.Integration.Status.Phase {
-		if err != nil {
-			e.Integration.Status.SetErrorCondition(v1.IntegrationConditionPlatformAvailable, v1.IntegrationConditionPlatformAvailableReason, err)
+		if initial.Status.Phase != e.Integration.Status.Phase {
+			e.Integration.Status.SetErrorCondition(
+				v1.IntegrationConditionPlatformAvailable,
+				v1.IntegrationConditionPlatformAvailableReason,
+				err)
+
+			if pl != nil {
+				e.Integration.SetIntegrationPlatform(pl)
+			}
 		}
-
-		if pl != nil {
+	case pl == nil:
+		e.Integration.Status.Phase = v1.IntegrationPhaseWaitingForPlatform
+	case pl.Status.Phase != v1.IntegrationPlatformPhaseReady:
+		e.Integration.Status.Phase = v1.IntegrationPhaseWaitingForPlatform
+		if initial.Status.Phase != e.Integration.Status.Phase {
 			e.Integration.SetIntegrationPlatform(pl)
 		}
+	default:
+		// In success case, phase should be reset to none
+		e.Integration.Status.Phase = v1.IntegrationPhaseNone
+		e.Integration.SetIntegrationPlatform(pl)
 	}
 
 	return nil
@@ -101,43 +112,42 @@ func (t *platformTrait) Apply(e *Environment) error {
 
 func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1.IntegrationPlatform, error) {
 	pl, err := platform.GetOrFindForResource(e.Ctx, t.Client, e.Integration, false)
-	if err != nil && apierrors.IsNotFound(err) {
-		if pointer.BoolDeref(t.CreateDefault, false) {
-			platformName := e.Integration.Status.Platform
-			if platformName == "" {
-				platformName = defaults.OperatorID()
-			}
-
-			if platformName == "" {
-				platformName = platform.DefaultPlatformName
-			}
-			namespace := e.Integration.Namespace
-			if pointer.BoolDeref(t.Global, false) {
-				operatorNamespace := platform.GetOperatorNamespace()
-				if operatorNamespace != "" {
-					namespace = operatorNamespace
-				}
-			}
-			defaultPlatform := v1.NewIntegrationPlatform(namespace, platformName)
-			if defaultPlatform.Labels == nil {
-				defaultPlatform.Labels = make(map[string]string)
-			}
-			defaultPlatform.Labels["camel.apache.org/platform.generated"] = True
-			// Cascade the operator id in charge to reconcile the Integration
-			if v1.GetOperatorIDAnnotation(e.Integration) != "" {
-				defaultPlatform.SetOperatorID(v1.GetOperatorIDAnnotation(e.Integration))
-			}
-			pl = &defaultPlatform
-			e.Resources.Add(pl)
+	if err != nil && apierrors.IsNotFound(err) && pointer.BoolDeref(t.CreateDefault, false) {
+		platformName := e.Integration.Status.Platform
+		if platformName == "" {
+			platformName = defaults.OperatorID()
+		}
 
-			// Make sure that IntegrationPlatform installed in operator namespace can be seen by others
-			if err := install.IntegrationPlatformViewerRole(e.Ctx, t.Client, namespace); err != nil && !apierrors.IsAlreadyExists(err) {
-				t.L.Info(fmt.Sprintf("Cannot install global IntegrationPlatform viewer role in namespace '%s': skipping.", namespace))
+		if platformName == "" {
+			platformName = platform.DefaultPlatformName
+		}
+		namespace := e.Integration.Namespace
+		if pointer.BoolDeref(t.Global, false) {
+			operatorNamespace := platform.GetOperatorNamespace()
+			if operatorNamespace != "" {
+				namespace = operatorNamespace
 			}
+		}
+		defaultPlatform := v1.NewIntegrationPlatform(namespace, platformName)
+		if defaultPlatform.Labels == nil {
+			defaultPlatform.Labels = make(map[string]string)
+		}
+		defaultPlatform.Labels["camel.apache.org/platform.generated"] = True
+		// Cascade the operator id in charge to reconcile the Integration
+		if v1.GetOperatorIDAnnotation(e.Integration) != "" {
+			defaultPlatform.SetOperatorID(v1.GetOperatorIDAnnotation(e.Integration))
+		}
+		pl = &defaultPlatform
+		e.Resources.Add(pl)
 
-			return pl, nil
+		// Make sure that IntegrationPlatform installed in operator namespace can be seen by others
+		if err := install.IntegrationPlatformViewerRole(e.Ctx, t.Client, namespace); err != nil && !apierrors.IsAlreadyExists(err) {
+			t.L.Info(fmt.Sprintf("Cannot install global IntegrationPlatform viewer role in namespace '%s': skipping.", namespace))
 		}
+
+		return pl, nil
 	}
+
 	return pl, err
 }
 
diff --git a/pkg/trait/platform_test.go b/pkg/trait/platform_test.go
index 02fe8e4f1..488cbb739 100644
--- a/pkg/trait/platform_test.go
+++ b/pkg/trait/platform_test.go
@@ -127,7 +127,7 @@ func TestPlatformTraitExisting(t *testing.T) {
 		{
 			name:          "Move state",
 			platformPhase: v1.IntegrationPlatformPhaseReady,
-			expectedPhase: v1.IntegrationPhaseInitialization,
+			expectedPhase: v1.IntegrationPhaseNone,
 		},
 	}
 


[camel-k] 06/07: fix(controller): monitor should reconcile integrations in initialisation failed condition

Posted by ts...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tsato pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 06d6300b46ccb1e4f708037040f84a9500474d33
Author: Tadayoshi Sato <sa...@gmail.com>
AuthorDate: Tue Sep 13 17:47:34 2022 +0900

    fix(controller): monitor should reconcile integrations in initialisation failed condition
---
 pkg/controller/integration/monitor.go | 87 +++++++++++++++++++++--------------
 1 file changed, 52 insertions(+), 35 deletions(-)

diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index 9909be03e..03aa86c67 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -57,58 +57,36 @@ func (action *monitorAction) Name() string {
 }
 
 func (action *monitorAction) CanHandle(integration *v1.Integration) bool {
-	// When in InitializationFailed condition a kit is not available for the integration
-	// so the monitor action is not able to handle it.
-	if isInInitializationFailed(integration.Status) {
-		return false
-	}
-
 	return integration.Status.Phase == v1.IntegrationPhaseDeploying ||
 		integration.Status.Phase == v1.IntegrationPhaseRunning ||
 		integration.Status.Phase == v1.IntegrationPhaseError
 }
 
-func isInInitializationFailed(status v1.IntegrationStatus) bool {
-	if status.Phase == v1.IntegrationPhaseError {
-		cond := status.GetCondition(v1.IntegrationConditionReady)
-		if cond.Status == corev1.ConditionFalse && cond.Reason == v1.IntegrationConditionInitializationFailedReason {
-			return true
-		}
+func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
+	// When in InitializationFailed condition a kit is not available for the integration
+	// so handle it differently from the rest
+	if isInInitializationFailed(integration.Status) {
+		// Only check if the Integration requires a rebuild
+		return action.checkDigestAndRebuild(integration, nil)
 	}
 
-	return false
-}
-
-func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
 	// At that staged the Integration must have a Kit
 	if integration.Status.IntegrationKit == nil {
 		return nil, fmt.Errorf("no kit set on integration %s", integration.Name)
 	}
 
-	kit, err := kubernetes.GetIntegrationKit(ctx, action.client, integration.Status.IntegrationKit.Name, integration.Status.IntegrationKit.Namespace)
+	kit, err := kubernetes.GetIntegrationKit(ctx, action.client,
+		integration.Status.IntegrationKit.Name, integration.Status.IntegrationKit.Namespace)
 	if err != nil {
-		return nil, fmt.Errorf("unable to find integration kit %s/%s: %w", integration.Status.IntegrationKit.Namespace, integration.Status.IntegrationKit.Name, err)
+		return nil, fmt.Errorf("unable to find integration kit %s/%s: %w",
+			integration.Status.IntegrationKit.Namespace, integration.Status.IntegrationKit.Name, err)
 	}
 
 	// Check if the Integration requires a rebuild
-	hash, err := digest.ComputeForIntegration(integration)
-	if err != nil {
+	if changed, err := action.checkDigestAndRebuild(integration, kit); err != nil {
 		return nil, err
-	}
-
-	if hash != integration.Status.Digest {
-		action.L.Info("Monitor: Integration needs a rebuild")
-
-		if v1.GetOperatorIDAnnotation(integration) != "" &&
-			(v1.GetOperatorIDAnnotation(integration) != v1.GetOperatorIDAnnotation(kit)) {
-			// Operator to reconcile the integration has changed. Reset integration kit so new operator can handle the kit reference
-			integration.SetIntegrationKit(nil)
-		}
-
-		integration.Initialize()
-		integration.Status.Digest = hash
-
-		return integration, nil
+	} else if changed != nil {
+		return changed, nil
 	}
 
 	// Check if an IntegrationKit with higher priority is ready
@@ -184,6 +162,45 @@ func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integra
 	return integration, nil
 }
 
+func isInInitializationFailed(status v1.IntegrationStatus) bool {
+	if status.Phase != v1.IntegrationPhaseError {
+		return false
+	}
+	if cond := status.GetCondition(v1.IntegrationConditionReady); cond != nil {
+		if cond.Status == corev1.ConditionFalse &&
+			cond.Reason == v1.IntegrationConditionInitializationFailedReason {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (action *monitorAction) checkDigestAndRebuild(integration *v1.Integration, kit *v1.IntegrationKit) (*v1.Integration, error) {
+	hash, err := digest.ComputeForIntegration(integration)
+	if err != nil {
+		return nil, err
+	}
+
+	if hash != integration.Status.Digest {
+		action.L.Info("Monitor: Integration needs a rebuild")
+
+		if kit != nil &&
+			v1.GetOperatorIDAnnotation(integration) != "" &&
+			v1.GetOperatorIDAnnotation(integration) != v1.GetOperatorIDAnnotation(kit) {
+			// Operator to reconcile the integration has changed. Reset integration kit so new operator can handle the kit reference
+			integration.SetIntegrationKit(nil)
+		}
+
+		integration.Initialize()
+		integration.Status.Digest = hash
+
+		return integration, nil
+	}
+
+	return nil, nil
+}
+
 type controller interface {
 	checkReadyCondition(ctx context.Context) (bool, error)
 	getPodSpec() corev1.PodSpec