Repository: apache/camel-k
Pull request #3632 (2022-09-12 14:03:27)

Update documentation for kamelet type that can also be action
the type can now also be action, not only source and sink.

For instance, see https://github.com/apache/camel-kamelets/blob/b98e61105b8c782422028b0c2ea857a90c97a550/kamelets/avro-deserialize-action.kamelet.yaml#L29

<!-- Description -->




<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
NONE
```



Patch:
diff --git a/.github/actions/release/action.yml b/.github/actions/release-nightly/action.yml
similarity index 94%
rename from .github/actions/release/action.yml
rename to .github/actions/release-nightly/action.yml
index 5c946baba..765cdcb99 100644
--- a/.github/actions/release/action.yml
+++ b/.github/actions/release-nightly/action.yml
@@ -13,7 +13,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-name: release-action
+name: release-nightly
 description: 'action used to release nightly'
 
 inputs:
@@ -26,11 +26,6 @@ inputs:
   javaVersion:
     required: true
     type: string
-secrets:
-  registryUsername:
-    required: true
-  registryPassword:
-    required: true
 
 runs:
   using: "composite"
@@ -88,8 +83,8 @@ runs:
     - name: Login to Container Registry
       uses: docker/login-action@v1
       with:
-        username: ${{ secrets.registryUsername }}
-        password: ${{ secrets.registryPassword }}
+        username: ${{ secrets.TEST_DOCKER_HUB_USERNAME }}
+        password: ${{ secrets.TEST_DOCKER_HUB_PASSWORD }}
 
     - name: Codegen
       run: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d12265ca3..af239def0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,35 +25,33 @@ jobs:
   main:
     if: github.repository == 'apache/camel-k'
     runs-on: ubuntu-20.04
-    uses: ./.github/actions/release
-    with:
-      ref: "main"
-      goVersion: "1.17.x"
-      javaVersion: "11"
-    secrets:
-      registryUsername: ${{ secrets.TEST_DOCKER_HUB_USERNAME }}
-      registryPassword: ${{ secrets.TEST_DOCKER_HUB_PASSWORD }}
+    steps:
+    - name: Release main nightly
+      uses: ./.github/actions/release-nightly
+      with:
+        ref: "main"
+        goVersion: "1.17.x"
+        javaVersion: "11"
 
   v1_10_x:
     if: github.repository == 'apache/camel-k'
     runs-on: ubuntu-20.04
-    uses: ./.github/actions/release
-    with:
-      ref: "release-1.10.x"
-      goVersion: "1.17.x"
-      javaVersion: "11"
-    secrets:
-      registryUsername: ${{ secrets.TEST_DOCKER_HUB_USERNAME }}
-      registryPassword: ${{ secrets.TEST_DOCKER_HUB_PASSWORD }}
+    steps:
+    - name: Release 1.10 nightly
+      uses: ./.github/actions/release-nightly
+      with:
+        ref: "release-1.10.x"
+        goVersion: "1.17.x"
+        javaVersion: "11"
 
   v1_9_x:
     if: github.repository == 'apache/camel-k'
     runs-on: ubuntu-20.04
-    uses: ./.github/actions/release
-    with:
-      ref: "release-1.9.x"
-      goVersion: "1.17.x"
-      javaVersion: "11"
-    secrets:
-      registryUsername: ${{ secrets.TEST_DOCKER_HUB_USERNAME }}
-      registryPassword: ${{ secrets.TEST_DOCKER_HUB_PASSWORD }}
+    steps:
+    - name: Release 1.9 nightly 
+      uses: ./.github/actions/release-nightly
+      with:
+        ref: "release-1.9.x"
+        goVersion: "1.17.x"
+        javaVersion: "11"
+        
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 584c95ecb..225e0f6e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,18 +6,19 @@
 
 **Closed issues:**
 
+- `make bundle` failure [\#3602](https://github.com/apache/camel-k/issues/3602)
 - Parametrize kaniko executor image to point to private registry [\#3350](https://github.com/apache/camel-k/issues/3350)
 - kamel uninstall --all does not remove Kamelets [\#3342](https://github.com/apache/camel-k/issues/3342)
 - Configure parallel container image layers push based on CPU quota [\#3340](https://github.com/apache/camel-k/issues/3340)
 - Configure Maven builds based on CPU quota [\#3339](https://github.com/apache/camel-k/issues/3339)
 - Flaky E2E tests identified in 1.9.x [\#3234](https://github.com/apache/camel-k/issues/3234)
 - kamel log tail option [\#3004](https://github.com/apache/camel-k/issues/3004)
+- Provide a command to add a repo for custom Kamelet catalog [\#2850](https://github.com/apache/camel-k/issues/2850)
 - Ability to set labels on knative service \(for things like "cluster-local"\) [\#1712](https://github.com/apache/camel-k/issues/1712)
 - kamel CLI - Allow to specify a namespace to use instead of default [\#1184](https://github.com/apache/camel-k/issues/1184)
 - Create a Github Action for Camel K [\#1163](https://github.com/apache/camel-k/issues/1163)
 - Camel K doesn't support kubernetes services of type loadbalancer [\#1070](https://github.com/apache/camel-k/issues/1070)
 - Camel-K operator should clean up kits and kit builders after integrations are deleted [\#889](https://github.com/apache/camel-k/issues/889)
-- Execute maven operation asynchronously [\#762](https://github.com/apache/camel-k/issues/762)
 - support for multiple type of builders [\#687](https://github.com/apache/camel-k/issues/687)
 
 ## [1.11.0-nightly](https://github.com/apache/camel-k/tree/1.11.0-nightly) (2022-09-06)
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/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/docs/modules/ROOT/pages/configuration/build-time-properties.adoc b/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
index 713c3f182..b8d239eb9 100644
--- a/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
+++ b/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
@@ -50,10 +50,70 @@ kamel run --build-property=file:quarkus.properties build-property-route.groovy
 
 The property file is parsed and its properties configured on the `Integration`. As soon as the application starts, you will see the log with the expected configuration.
 
+[[build-time-configmap]]
+== Property from ConfigMap/Secret
+
+In case some build-time properties are stored into a `Configmap` or a `Secret`, you can use the `--build-property` flag with a value of type respectively _configmap:name-of-configmap_ or _secret:name-of-secret_ to refer to the specific resource to use as build-time properties.
+
+As an example, let's create a `Configmap` named _my-cm-bp_ containing the build-time properties to load. You can alternatively use any `Configmap` you've already stored in your cluster:
+
+----
+kubectl create configmap my-cm-bp --from-literal=quarkus.application.name="my-great-application" --from-literal=quarkus.banner.enabled="true"
+----
+
+Here, as an example we have create a configmap with 2 `Quarkus` properties.
+
+[source,groovy]
+.build-property-route.groovy
+----
+from('timer:build-property')
+    .log('The application name: {{quarkus.application.name}}')
+----
+
+The `quarkus.banner.enabled` is configured to show the banner during the `Integration` startup. Let's use `--build-property` flag in conjunction with file:
+
+----
+kamel run --build-property=configmap:my-cm-bp build-property-route.groovy
+----
+
+The key-value pairs of the `ConfigMap` are loaded and used as build-time properties of the `Integration`. As soon as the application starts, you will see the log with the expected configuration.
+
+[[build-time-configmap-as-file]]
+== Property from ConfigMap/Secret as file
+
+When you have a lot of key-value pairs to store into a given `ConfigMap`/`Secret`, you may consider storing some build-time properties as a file into a specific key-value pair for the sake of simplicity. 
+
+The only constraint is to use `.properties` as a suffix of the key to indicate that the value is actually a property file, not a simple value.
+
+As an example, let's use the same `Integration` as the previous section but with a `ConfigMap` that contains all the properties into the same key-value pair.
+
+For this we need a properties file as next:
+
+[source,properties]
+.quarkus.properties
+----
+quarkus.application.name = my-super-application
+quarkus.banner.enabled = true
+----
+
+That we will load into a specific `ConfigMap` using the following command:
+
+----
+kubectl create configmap my-cm-bps --from-file=quarkus.properties
+----
+
+Then we launch the `run` command with the `--build-property` flag whose value matches with the appropriate syntax to refer to `my-cm-bps`:
+
+----
+kamel run --build-property configmap:my-cm-bps build-property-route.groovy
+----
+
+The value of the key-value of the `ConfigMap` is loaded as a property file and used as build-time properties of the `Integration`. you will see the log with the expected configuration.
+
 [[build-time-props-file-precedence]]
 == Property collision priority
 
-If you have a property repeated more than once, the general rule is that the last one declared in your `kamel run` statement will be taken in consideration. If the same property is found both in a single option declaration and inside a file, then, the single option will have higher priority and will be used.
+If you have a property repeated more than once, the general rule is that the last one declared in your `kamel run` statement will be taken in consideration. If the same property is found both in a single option declaration and inside a file/configmap/secret, then, the single option will have higher priority and will be used.
 
 [[build-time-runtime-conf]]
 == Run time properties
diff --git a/docs/modules/ROOT/pages/configuration/runtime-properties.adoc b/docs/modules/ROOT/pages/configuration/runtime-properties.adoc
index c65b5efb2..6ea961640 100644
--- a/docs/modules/ROOT/pages/configuration/runtime-properties.adoc
+++ b/docs/modules/ROOT/pages/configuration/runtime-properties.adoc
@@ -67,10 +67,70 @@ kamel run --property file:my.properties property-route.groovy
 
 The property file is parsed and its properties configured on the `Integration`. As soon as the application starts, you will see the log with the expected configuration.
 
+[[runtime-configmap]]
+== Property from ConfigMap/Secret
+
+In case some runtime properties are stored into a `Configmap` or a `Secret`, you can use the `--property` flag with a value of type respectively _configmap:name-of-configmap_ or _secret:name-of-secret_ to refer to the specific resource to use as runtime properties.
+
+As an example, let's create a `Configmap` named _my-cm-rp_ containing the runtime properties to load. You can alternatively use any `Configmap` you've already stored in your cluster:
+
+----
+kubectl create configmap my-cm-rp --from-literal=name="Will Smith" --from-literal=period="2000"
+----
+
+In our `Integration` we can simply refer to the properties defined in the `ConfigMap` as we'd do with any other property:
+
+[source,groovy]
+.property-configmap-route.groovy
+----
+from('timer:property?period={{period}}')
+    .log('Hello {{name}}!')
+----
+
+Then we launch the `run` command with the `--property` flag whose value matches with the appropriate syntax to refer to `my-cm-rp`:
+
+----
+kamel run --property configmap:my-cm-rp property-configmap-route.groovy
+----
+
+The key-value pairs of the `ConfigMap` are loaded and used as runtime properties of the `Integration`. As soon as the application starts, you will see the log with the expected message.
+
+[[runtime-configmap-as-file]]
+== Property from ConfigMap/Secret as file
+
+When you have a lot of key-value pairs to store into a given `ConfigMap`/`Secret`, you may consider storing some runtime properties as a file into a specific key-value pair for the sake of simplicity. 
+
+The only constraint is to use `.properties` as a suffix of the key to indicate that the value is actually a property file, not a simple value.
+
+As an example, let's use the same `Integration` as the previous section but with a `ConfigMap` that contains all the properties into the same key-value pair.
+
+For this we need a properties file as next:
+
+[source,text]
+.some.properties
+----
+name=John Smith
+period=2000
+----
+
+That we will load into a specific `ConfigMap` using the following command:
+
+----
+kubectl create configmap my-cm-rps --from-file=some.properties
+----
+
+Then we launch the `run` command with the `--property` flag whose value matches with the appropriate syntax to refer to `my-cm-rps`:
+
+----
+kamel run --property configmap:my-cm-rps property-configmap-route.groovy
+----
+
+The value of the key-value of the `ConfigMap` is loaded as a property file and used as runtime properties of the `Integration`. As soon as the application starts, you will see the log with the expected message.
+
 [[runtime-props-file-precedence]]
 == Property collision priority
 
-If you have a property repeated more than once, the general rule is that the last one declared in your `kamel run` statement will be taken in consideration. If the same property is found both in a single option declaration and inside a file, then, the single option will have higher priority and will be used.
+If you have a property repeated more than once, the general rule is that the last one declared in your `kamel run` statement will be taken in consideration. If the same property is found both in a single option declaration and inside a file/configmap/secret, then, the single option will have higher priority and will be used.
 
 [[runtime-build-time-conf]]
 == Build time properties
diff --git a/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc b/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
index 34643b3f6..9fad54806 100644
--- a/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
+++ b/docs/modules/ROOT/pages/kamelets/kamelets-user.adoc
@@ -466,8 +466,8 @@ The following annotations and labels are also defined on the resource:
 |name |Description |Type |Example
 
 |label: `camel.apache.org/kamelet.type`
-|Indicates if the Kamelet can be used as source or sink
-|enum: `source`, `sink`
+|Indicates if the Kamelet can be used as source, action or sink.
+|enum: `source`, `action`, `sink`
 |E.g. `source`
 |===
 
diff --git a/helm/camel-k/templates/operator.yaml b/helm/camel-k/templates/operator.yaml
index b154e1641..a26f4c57e 100644
--- a/helm/camel-k/templates/operator.yaml
+++ b/helm/camel-k/templates/operator.yaml
@@ -84,4 +84,4 @@ spec:
       {{- with .Values.operator.tolerations }}
       tolerations:
         {{- toYaml . | nindent 8 }}
-      {{-end }}
+      {{- end }}
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/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 3ba0c2768..921b2d74f 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 --
@@ -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/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/cmd/run.go b/pkg/cmd/run.go
index ac4174ff4..301aa05b3 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -101,8 +101,8 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions)
 	cmd.Flags().StringArrayP("dependency", "d", nil, usageDependency)
 	cmd.Flags().BoolP("wait", "w", false, "Wait for the integration to be running")
 	cmd.Flags().StringP("kit", "k", "", "The kit used to run the integration")
-	cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file (syntax: [my-key=my-value|file:/path/to/my-conf.properties])")
-	cmd.Flags().StringArray("build-property", nil, "Add a build time property or properties file (syntax: [my-key=my-value|file:/path/to/my-conf.properties])")
+	cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file from a path, a config map or a secret (syntax: [my-key=my-value|file:/path/to/my-conf.properties|[configmap|secret]:name])")
+	cmd.Flags().StringArray("build-property", nil, "Add a build time property or properties file from a path, a config map or a secret (syntax: [my-key=my-value|file:/path/to/my-conf.properties|[configmap|secret]:name]])")
 	cmd.Flags().StringArray("config", nil, "Add a runtime configuration from a Configmap, a Secret or a file (syntax: [configmap|secret|file]:name[/key], where name represents the local file path or the configmap/secret name and key optionally represents the configmap/secret key to be filtered)")
 	cmd.Flags().StringArray("resource", nil, "Add a runtime resource from a Configmap, a Secret or a file (syntax: [configmap|secret|file]:name[/key][@path], where name represents the local file path or the configmap/secret name, key optionally represents the configmap/secret key to be filtered and path represents the destination path)")
 	cmd.Flags().StringArray("maven-repository", nil, "Add a maven repository")
@@ -694,11 +694,11 @@ func (o *runCmdOptions) convertOptionsToTraits(cmd *cobra.Command, c client.Clie
 		return err
 	}
 
-	if err := o.applyProperties(); err != nil {
+	if err := o.applyProperties(c); err != nil {
 		return err
 	}
 
-	if err := o.applyBuildProperties(); err != nil {
+	if err := o.applyBuildProperties(c); err != nil {
 		return err
 	}
 
@@ -738,14 +738,14 @@ func convertToTrait(value, traitParameter string) string {
 	return fmt.Sprintf("%s=%s", traitParameter, value)
 }
 
-func (o *runCmdOptions) applyProperties() error {
-	props, err := mergePropertiesWithPrecedence(o.Properties)
+func (o *runCmdOptions) applyProperties(c client.Client) error {
+	props, err := o.mergePropertiesWithPrecedence(c, o.Properties)
 	if err != nil {
 		return err
 	}
 	for _, key := range props.Keys() {
 		kv := fmt.Sprintf("%s=%s", key, props.GetString(key, ""))
-		propsTraits, err := convertToTraitParameter(kv, "camel.properties")
+		propsTraits, err := o.convertToTraitParameter(c, kv, "camel.properties")
 		if err != nil {
 			return err
 		}
@@ -755,15 +755,15 @@ func (o *runCmdOptions) applyProperties() error {
 	return nil
 }
 
-func (o *runCmdOptions) applyBuildProperties() error {
+func (o *runCmdOptions) applyBuildProperties(c client.Client) error {
 	// convert each build configuration to a builder trait property
-	buildProps, err := mergePropertiesWithPrecedence(o.BuildProperties)
+	buildProps, err := o.mergePropertiesWithPrecedence(c, o.BuildProperties)
 	if err != nil {
 		return err
 	}
 	for _, key := range buildProps.Keys() {
 		kv := fmt.Sprintf("%s=%s", key, buildProps.GetString(key, ""))
-		buildPropsTraits, err := convertToTraitParameter(kv, "builder.properties")
+		buildPropsTraits, err := o.convertToTraitParameter(c, kv, "builder.properties")
 		if err != nil {
 			return err
 		}
@@ -773,9 +773,9 @@ func (o *runCmdOptions) applyBuildProperties() error {
 	return nil
 }
 
-func convertToTraitParameter(value, traitParameter string) ([]string, error) {
+func (o *runCmdOptions) convertToTraitParameter(c client.Client, value, traitParameter string) ([]string, error) {
 	traits := make([]string, 0)
-	props, err := extractProperties(value)
+	props, err := o.extractProperties(c, value)
 	if err != nil {
 		return nil, err
 	}
@@ -852,6 +852,43 @@ func (o *runCmdOptions) GetIntegrationName(sources []string) string {
 	return name
 }
 
+func (o *runCmdOptions) mergePropertiesWithPrecedence(c client.Client, items []string) (*properties.Properties, error) {
+	loPrecedenceProps := properties.NewProperties()
+	hiPrecedenceProps := properties.NewProperties()
+	for _, item := range items {
+		prop, err := o.extractProperties(c, item)
+		if err != nil {
+			return nil, err
+		}
+		// We consider file, secret and config map props to have a lower priority versus single properties
+		if strings.HasPrefix(item, "file:") || strings.HasPrefix(item, "secret:") || strings.HasPrefix(item, "configmap:") {
+			loPrecedenceProps.Merge(prop)
+		} else {
+			hiPrecedenceProps.Merge(prop)
+		}
+	}
+	// Any property contained in both collections will be merged
+	// giving precedence to the ones in hiPrecedenceProps
+	loPrecedenceProps.Merge(hiPrecedenceProps)
+	return loPrecedenceProps, nil
+}
+
+// The function parse the value and if it is a file (file:/path/), it will parse as property file
+// otherwise return a single property built from the item passed as `key=value`.
+func (o *runCmdOptions) extractProperties(c client.Client, value string) (*properties.Properties, error) {
+	switch {
+	case strings.HasPrefix(value, "file:"):
+		// we already validated the existence of files during validate()
+		return loadPropertyFile(strings.Replace(value, "file:", "", 1))
+	case strings.HasPrefix(value, "secret:"):
+		return loadPropertiesFromSecret(o.Context, c, o.Namespace, strings.Replace(value, "secret:", "", 1))
+	case strings.HasPrefix(value, "configmap:"):
+		return loadPropertiesFromConfigMap(o.Context, c, o.Namespace, strings.Replace(value, "configmap:", "", 1))
+	default:
+		return keyValueProps(value)
+	}
+}
+
 func loadPropertyFile(fileName string) (*properties.Properties, error) {
 	file, err := util.ReadFile(fileName)
 	if err != nil {
diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go
index c885e4151..328e9be32 100644
--- a/pkg/cmd/run_help.go
+++ b/pkg/cmd/run_help.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"fmt"
 	"path"
+	"reflect"
 	"strings"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
@@ -115,37 +116,48 @@ func filterFileLocation(maybeFileLocations []string) []string {
 	return filteredOptions
 }
 
-func mergePropertiesWithPrecedence(items []string) (*properties.Properties, error) {
-	loPrecedenceProps := properties.NewProperties()
-	hiPrecedenceProps := properties.NewProperties()
-	for _, item := range items {
-		prop, err := extractProperties(item)
-		if err != nil {
-			return nil, err
-		}
-		// We consider file props to have a lower priority versus single properties
-		if strings.HasPrefix(item, "file:") {
-			loPrecedenceProps.Merge(prop)
-		} else {
-			hiPrecedenceProps.Merge(prop)
-		}
+func keyValueProps(value string) (*properties.Properties, error) {
+	return properties.Load([]byte(value), properties.UTF8)
+}
+
+func loadPropertiesFromSecret(ctx context.Context, c client.Client, ns string, name string) (*properties.Properties, error) {
+	secret := kubernetes.LookupSecret(ctx, c, ns, name)
+	if secret == nil {
+		return nil, fmt.Errorf("%s secret not found in %s namespace, make sure to provide it before the Integration can run", name, ns)
 	}
-	// Any property contained in both collections will be merged
-	// giving precedence to the ones in hiPrecedenceProps
-	loPrecedenceProps.Merge(hiPrecedenceProps)
-	return loPrecedenceProps, nil
+	return fromMapToProperties(secret.Data,
+		func(v reflect.Value) string { return string(v.Bytes()) },
+		func(v reflect.Value) (*properties.Properties, error) {
+			return properties.Load(v.Bytes(), properties.UTF8)
+		})
 }
 
-// The function parse the value and if it is a file (file:/path/), it will parse as property file
-// otherwise return a single property built from the item passed as `key=value`.
-func extractProperties(value string) (*properties.Properties, error) {
-	if !strings.HasPrefix(value, "file:") {
-		return keyValueProps(value)
+func loadPropertiesFromConfigMap(ctx context.Context, c client.Client, ns string, name string) (*properties.Properties, error) {
+	cm := kubernetes.LookupConfigmap(ctx, c, ns, name)
+	if cm == nil {
+		return nil, fmt.Errorf("%s configmap not found in %s namespace, make sure to provide it before the Integration can run", name, ns)
 	}
-	// we already validated the existence of files during validate()
-	return loadPropertyFile(strings.Replace(value, "file:", "", 1))
+	return fromMapToProperties(cm.Data,
+		func(v reflect.Value) string { return v.String() },
+		func(v reflect.Value) (*properties.Properties, error) { return keyValueProps(v.String()) })
 }
 
-func keyValueProps(value string) (*properties.Properties, error) {
-	return properties.Load([]byte(value), properties.UTF8)
+func fromMapToProperties(data interface{}, toString func(reflect.Value) string, loadProperties func(reflect.Value) (*properties.Properties, error)) (*properties.Properties, error) {
+	result := properties.NewProperties()
+	m := reflect.ValueOf(data)
+	for _, k := range m.MapKeys() {
+		key := k.String()
+		value := m.MapIndex(k)
+		if strings.HasSuffix(key, ".properties") {
+			p, err := loadProperties(value)
+			if err == nil {
+				result.Merge(p)
+			} else if _, _, err = result.Set(key, toString(value)); err != nil {
+				return nil, fmt.Errorf("cannot assign %s to %s", value, key)
+			}
+		} else if _, _, err := result.Set(key, toString(value)); err != nil {
+			return nil, fmt.Errorf("cannot assign %s to %s", value, key)
+		}
+	}
+	return result, nil
 }
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..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 {
@@ -344,22 +353,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 +377,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 +386,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..03aa86c67 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -63,35 +63,30 @@ func (action *monitorAction) CanHandle(integration *v1.Integration) bool {
 }
 
 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)
+	}
+
 	// 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
@@ -167,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
@@ -177,7 +211,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 +221,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 +231,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 +291,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 +304,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 +321,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 +450,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 +487,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
 }
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/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/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/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/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/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/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")
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)
+}


Test patch:
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/e2e/global/common/config/config_test.go b/e2e/global/common/config/config_test.go
index 9363fb391..a525ec273 100644
--- a/e2e/global/common/config/config_test.go
+++ b/e2e/global/common/config/config_test.go
@@ -68,6 +68,54 @@ func TestRunConfigExamples(t *testing.T) {
 			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 		})
 
+		t.Run("Property from ConfigMap", func(t *testing.T) {
+			var cmData = make(map[string]string)
+			cmData["my.message"] = "my-configmap-property-value"
+			CreatePlainTextConfigmap(ns, "my-cm-test-property", cmData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-property").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-value"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Property from ConfigMap as property file", func(t *testing.T) {
+			var cmData = make(map[string]string)
+			cmData["my.properties"] = "my.message=my-configmap-property-entry"
+			CreatePlainTextConfigmap(ns, "my-cm-test-properties", cmData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-properties").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-entry"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Property from Secret", func(t *testing.T) {
+			var secData = make(map[string]string)
+			secData["my.message"] = "my-secret-property-value"
+			CreatePlainTextSecret(ns, "my-sec-test-property", secData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-property").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-value"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Property from Secret as property file", func(t *testing.T) {
+			var secData = make(map[string]string)
+			secData["my.properties"] = "my.message=my-secret-property-entry"
+			CreatePlainTextSecret(ns, "my-sec-test-properties", secData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-properties").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-entry"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
 		// Configmap
 
 		// Store a configmap on the cluster
@@ -274,5 +322,52 @@ func TestRunConfigExamples(t *testing.T) {
 			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 		})
 
+		t.Run("Build time property from ConfigMap", func(t *testing.T) {
+			var cmData = make(map[string]string)
+			cmData["quarkus.application.name"] = "my-cool-application"
+			CreatePlainTextConfigmap(ns, "my-cm-test-build-property", cmData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-property").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-cool-application"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Build time property from ConfigMap as property file", func(t *testing.T) {
+			var cmData = make(map[string]string)
+			cmData["my.properties"] = "quarkus.application.name=my-super-cool-application"
+			CreatePlainTextConfigmap(ns, "my-cm-test-build-properties", cmData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-properties").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-cool-application"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Build time property from Secret", func(t *testing.T) {
+			var secData = make(map[string]string)
+			secData["quarkus.application.name"] = "my-great-application"
+			CreatePlainTextSecret(ns, "my-sec-test-build-property", secData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-property").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-great-application"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+
+		t.Run("Build time property from Secret as property file", func(t *testing.T) {
+			var secData = make(map[string]string)
+			secData["my.properties"] = "quarkus.application.name=my-awsome-application"
+			CreatePlainTextSecret(ns, "my-sec-test-build-properties", secData)
+
+			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-properties").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-awsome-application"))
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
 	})
 }
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/Unresolvable.java b/e2e/global/common/files/Unresolvable.java
new file mode 100644
index 000000000..768f32ad4
--- /dev/null
+++ b/e2e/global/common/files/Unresolvable.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.camel.builder.RouteBuilder;
+
+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..cf999630c 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,31 @@ 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())
+
+			// 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())
diff --git a/pkg/cmd/run_help_test.go b/pkg/cmd/run_help_test.go
index 0fa7c9a96..175d4da93 100644
--- a/pkg/cmd/run_help_test.go
+++ b/pkg/cmd/run_help_test.go
@@ -18,8 +18,6 @@ limitations under the License.
 package cmd
 
 import (
-	"io/ioutil"
-	"os"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -41,64 +39,3 @@ func TestFilterFileLocation(t *testing.T) {
 	assert.Equal(t, "app.properties", filteredOptions[1])
 	assert.Equal(t, "/validfile", filteredOptions[2])
 }
-
-func TestExtractProperties_SingleKeyValue(t *testing.T) {
-	correctValues := []string{"key=val", "key = val", "key= val", " key   =  val"}
-	for _, val := range correctValues {
-		prop, err := extractProperties(val)
-		assert.Nil(t, err)
-		value, ok := prop.Get("key")
-		assert.True(t, ok)
-		assert.Equal(t, "val", value)
-	}
-}
-
-func TestExtractProperties_FromFile(t *testing.T) {
-	var tmpFile1 *os.File
-	var err error
-	if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
-		t.Error(err)
-	}
-
-	assert.Nil(t, tmpFile1.Close())
-	assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
-	key=value
-	#key2=value2
-	my.key=value
-	`), 0o400))
-
-	props, err := extractProperties("file:" + tmpFile1.Name())
-	assert.Nil(t, err)
-	assert.Equal(t, 2, props.Len())
-	for _, prop := range props.Keys() {
-		value, ok := props.Get(prop)
-		assert.True(t, ok)
-		assert.Equal(t, "value", value)
-	}
-}
-
-func TestExtractPropertiesFromFileAndSingleValue(t *testing.T) {
-	var tmpFile1 *os.File
-	var err error
-	if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
-		t.Error(err)
-	}
-
-	assert.Nil(t, tmpFile1.Close())
-	assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
-	key=value
-	#key2=value2
-	my.key=value
-	`), 0o400))
-
-	properties := []string{"key=override", "file:" + tmpFile1.Name(), "my.key = override"}
-	props, err := mergePropertiesWithPrecedence(properties)
-	assert.Nil(t, err)
-	assert.Equal(t, 2, props.Len())
-	val, ok := props.Get("key")
-	assert.True(t, ok)
-	assert.Equal(t, "override", val)
-	val, ok = props.Get("my.key")
-	assert.True(t, ok)
-	assert.Equal(t, "override", val)
-}
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index b02f37698..2b7144071 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -274,6 +274,69 @@ f=g:h
 i=j\nk
 `
 
+func TestExtractProperties_SingleKeyValue(t *testing.T) {
+	correctValues := []string{"key=val", "key = val", "key= val", " key   =  val"}
+	runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t)
+	for _, val := range correctValues {
+		prop, err := runCmdOptions.extractProperties(nil, val)
+		assert.Nil(t, err)
+		value, ok := prop.Get("key")
+		assert.True(t, ok)
+		assert.Equal(t, "val", value)
+	}
+}
+
+func TestExtractProperties_FromFile(t *testing.T) {
+	var tmpFile1 *os.File
+	var err error
+	if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
+		t.Error(err)
+	}
+
+	assert.Nil(t, tmpFile1.Close())
+	assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
+	key=value
+	#key2=value2
+	my.key=value
+	`), 0o400))
+	runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t)
+	props, err := runCmdOptions.extractProperties(nil, "file:"+tmpFile1.Name())
+	assert.Nil(t, err)
+	assert.Equal(t, 2, props.Len())
+	for _, prop := range props.Keys() {
+		value, ok := props.Get(prop)
+		assert.True(t, ok)
+		assert.Equal(t, "value", value)
+	}
+}
+
+func TestExtractPropertiesFromFileAndSingleValue(t *testing.T) {
+	var tmpFile1 *os.File
+	var err error
+	if tmpFile1, err = ioutil.TempFile("", "camel-k-*.properties"); err != nil {
+		t.Error(err)
+	}
+
+	assert.Nil(t, tmpFile1.Close())
+	assert.Nil(t, ioutil.WriteFile(tmpFile1.Name(), []byte(`
+	key=value
+	#key2=value2
+	my.key=value
+	`), 0o400))
+
+	properties := []string{"key=override", "file:" + tmpFile1.Name(), "my.key = override"}
+	runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t)
+	props, err := runCmdOptions.mergePropertiesWithPrecedence(nil, properties)
+	assert.Nil(t, err)
+	assert.Equal(t, 2, props.Len())
+	val, ok := props.Get("key")
+	assert.True(t, ok)
+	assert.Equal(t, "override", val)
+	val, ok = props.Get("my.key")
+	assert.True(t, ok)
+	assert.Equal(t, "override", val)
+}
+
 func TestAddPropertyFile(t *testing.T) {
 	var tmpFile *os.File
 	var err error
@@ -284,7 +347,8 @@ func TestAddPropertyFile(t *testing.T) {
 	assert.Nil(t, tmpFile.Close())
 	assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte(TestPropertyFileContent), 0o400))
 
-	properties, err := convertToTraitParameter("file:"+tmpFile.Name(), "trait.properties")
+	runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t)
+	properties, err := runCmdOptions.convertToTraitParameter(nil, "file:"+tmpFile.Name(), "trait.properties")
 	assert.Nil(t, err)
 	assert.Equal(t, 3, len(properties))
 	assert.Equal(t, `trait.properties=a = b`, properties[0])
@@ -293,7 +357,8 @@ func TestAddPropertyFile(t *testing.T) {
 }
 
 func TestRunProperty(t *testing.T) {
-	properties, err := convertToTraitParameter(`key=value\nnewline`, "trait.properties")
+	runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t)
+	properties, err := runCmdOptions.convertToTraitParameter(nil, `key=value\nnewline`, "trait.properties")
 	assert.Nil(t, err)
 	assert.Equal(t, 1, len(properties))
 	assert.Equal(t, `trait.properties=key = value\nnewline`, properties[0])
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..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,9 +44,10 @@ func TestDependenciesJavaSource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -70,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");
 			    '"'
 		    `,
 		},
@@ -78,9 +78,10 @@ func TestDependenciesJavaScript(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -103,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}}');
 			    '"
@@ -113,9 +113,10 @@ func TestDependenciesGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -144,9 +145,10 @@ func TestDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -158,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{
@@ -176,10 +199,11 @@ func TestDependenciesQuarkus(t *testing.T) {
 	}
 
 	catalog, err := camel.QuarkusCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 	assert.NotNil(t, catalog)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -207,9 +231,10 @@ func TestJacksonDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -235,9 +260,10 @@ func TestJacksonImplicitDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -269,9 +295,10 @@ func TestLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -303,9 +330,10 @@ func TestLanguageDependenciesTransformExpression(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -333,9 +361,10 @@ func TestCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(t,
 		[]string{
@@ -363,9 +392,10 @@ func TestRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -395,9 +425,10 @@ func TestRestWithPathDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -425,9 +456,10 @@ func TestRestConfigurationDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t, []string{
@@ -454,9 +486,10 @@ func TestRestClosureDependencyGroovy(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -484,9 +517,10 @@ func TestRestClosureDependencyKotlin(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -518,9 +552,10 @@ func TestXMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -557,9 +592,10 @@ func TestXMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -614,9 +650,10 @@ func TestXMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 	assert.ElementsMatch(
 		t,
 		[]string{
@@ -684,9 +721,10 @@ func TestYAMLRestDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -710,9 +748,10 @@ func TestYAMLCircuitBreakerDependency(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
@@ -733,9 +772,10 @@ func TestYAMLLanguageDependencies(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.ElementsMatch(
 		t,
diff --git a/pkg/metadata/metadata_http_test.go b/pkg/metadata/metadata_http_test.go
index 3f653acdf..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,16 +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.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.NoError(t, err)
 
 	assert.True(t, meta.ExposesHTTPServices)
 	assert.True(t, meta.PassiveEndpoints)
@@ -120,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");
 		`,
 		},
@@ -128,9 +132,10 @@ func TestNoHttpGroovySource(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := Extract(catalog, code)
+	meta, err := Extract(catalog, code)
+	require.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)
+	require.NoError(t, err)
 
-	meta := ExtractAll(catalog, codes)
+	meta, err := ExtractAll(catalog, codes)
+	require.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)
+	require.NoError(t, err)
 
-	meta := ExtractAll(catalog, codes)
+	meta, err := ExtractAll(catalog, codes)
+	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 90d526e9e..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,9 +48,10 @@ func TestJava1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -74,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");
   				}
 			}
 		`,
@@ -84,15 +86,16 @@ func TestJava2(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	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)
 }
 
@@ -107,25 +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.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	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)
 }
 
@@ -136,26 +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.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	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)
 }
 
@@ -181,9 +186,10 @@ func TestXml1(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	require.NoError(t, err)
 
 	assert.Contains(t, metadata.FromURIs, "timer:hello?period=3000")
 	assert.Len(t, metadata.FromURIs, 1)
@@ -204,29 +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.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	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)
 }
 
@@ -238,23 +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.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	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)
 }
 
@@ -282,9 +290,10 @@ func TestJYaml(t *testing.T) {
 	}
 
 	catalog, err := camel.DefaultCatalog()
-	assert.Nil(t, err)
+	require.NoError(t, err)
 
-	metadata := Extract(catalog, source)
+	metadata, err := Extract(catalog, source)
+	require.NoError(t, err)
 
 	assert.NotEmpty(t, metadata.FromURIs)
 	assert.Contains(t, metadata.FromURIs, "timer:tick")
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/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,
 		},
 	}