You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2018/12/21 11:05:53 UTC

[camel-k] branch master updated (9da7fd0 -> 11ca9c6)

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

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


    from 9da7fd0  Remove the "./" prefix before sanitizing the integration name. (#309)
     new e48fe40  add support for a simple yaml flow
     new 9b7ce11  create knative context #183
     new 0572cd2  chore(lint): fix findings
     new 11ca9c6  inspect xml source code using streaming parser

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


Summary of changes:
 deploy/platform-integration-context-groovy.yaml    |   2 +-
 deploy/platform-integration-context-jvm.yaml       |   2 +-
 ...l => platform-integration-context-knative.yaml} |   9 +-
 deploy/platform-integration-context-kotlin.yaml    |   2 +-
 .../platform-integration-context-spring-boot.yaml  |   2 +-
 deploy/resources.go                                |  26 ++++-
 examples/routes.flow                               |   5 +
 pkg/apis/camel/v1alpha1/types.go                   |  13 +++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   |  37 +++++++
 pkg/builder/builder_steps.go                       |  12 ++-
 pkg/builder/springboot/generator.go                |   8 ++
 pkg/client/cmd/install.go                          |   4 +-
 pkg/install/operator.go                            |   1 +
 pkg/metadata/dependencies.go                       |   3 +
 pkg/metadata/languages.go                          |   3 +-
 pkg/metadata/metadata.go                           |   7 +-
 pkg/metadata/metadata_uri_test.go                  |  28 ++++++
 pkg/stub/action/platform/create.go                 |  15 ++-
 pkg/trait/dependencies.go                          |   7 +-
 pkg/util/envvar/envvar.go                          |   3 +-
 pkg/util/kubernetes/collection.go                  |   3 +-
 pkg/util/kubernetes/loader.go                      |   1 +
 pkg/util/maven/maven_project.go                    |  11 ++-
 pkg/{metadata/uris.go => util/source/inspector.go} |  62 +++++-------
 .../main.go => pkg/util/source/inspector_groovy.go |  57 +++++------
 .../util/source/inspector_java_script.go           |  57 +++++------
 .../config.go => source/inspector_java_source.go}  |  48 ++++-----
 .../config.go => source/inspector_kotlin.go}       |  48 ++++-----
 pkg/util/source/inspector_xml.go                   |  89 +++++++++++++++++
 pkg/util/source/inspector_yaml_flow.go             |  67 +++++++++++++
 .../java/org/apache/camel/k/InMemoryRegistry.java  |  81 ++++++++++++++++
 .../src/main/java/org/apache/camel/k/Language.java |   4 +
 .../org/apache/camel/k/support/RuntimeSupport.java | 108 +++++++++++++++++++++
 .../org/apache/camel/k/support}/URIResolver.java   |   2 +-
 .../camel/k/groovy/GroovyRoutesLoader.groovy       |   2 +-
 .../org/apache/camel/k/groovy/LoaderTest.groovy    |   6 +-
 .../java/org/apache/camel/k/jvm/Application.java   |   7 +-
 ...RuntimeSupport.java => ApplicationSupport.java} |  86 +---------------
 .../main/java/org/apache/camel/k/jvm/Runtime.java  |  70 +------------
 .../camel/k/jvm/loader/JavaScriptLoader.java       |   2 +-
 .../camel/k/jvm/loader/JavaSourceLoader.java       |   2 +-
 .../org/apache/camel/k/jvm/loader/XmlLoader.java   |   2 +-
 .../org/apache/camel/k/jvm/PropertiesTest.java     |   2 +-
 .../org/apache/camel/k/jvm/RoutesLoadersTest.java  |  18 ++--
 .../java/org/apache/camel/k/jvm/RuntimeTest.java   |   2 +-
 .../apache/camel/k/kotlin/KotlinRoutesLoader.kt    |   2 +-
 .../kotlin/org/apache/camel/k/kotlin/LoaderTest.kt |   6 +-
 .../apache/camel/k/spring/boot/Application.java    |   7 +-
 .../pom.xml                                        |  24 +++--
 .../org/apache/camel/k/yaml/YamlFlowLoader.java    | 104 ++++++++++++++++++++
 .../org/apache/camel/k/yaml/model/Endpoint.java}   |  31 +++++-
 .../java/org/apache/camel/k/yaml/model/Flow.java}  |  16 ++-
 .../java/org/apache/camel/k/yaml/model/Step.java}  |  29 +++---
 .../apache/camel/k/yaml/model/StepHandler.java}    |  17 ++--
 .../k/yaml/model/handler/EndpointHandler.java}     |  21 +++-
 .../services/org/apache/camel/k/loader/yaml-flow}  |   2 +-
 .../org/apache/camel/k/yaml/flow/endpoint}         |   2 +-
 .../org/apache/camel/k/yaml/RoutesLoaderTest.java  |  51 ++++++++++
 .../src/test/resources/log4j2-test.xml             |   0
 .../src/test/resources/routes.flow                 |   5 +
 runtime/pom.xml                                    |   1 +
 61 files changed, 950 insertions(+), 394 deletions(-)
 copy deploy/{platform-integration-context-kotlin.yaml => platform-integration-context-knative.yaml} (63%)
 create mode 100644 examples/routes.flow
 rename pkg/{metadata/uris.go => util/source/inspector.go} (53%)
 copy cmd/kamel/main.go => pkg/util/source/inspector_groovy.go (54%)
 copy cmd/kamel/main.go => pkg/util/source/inspector_java_script.go (54%)
 copy pkg/util/{kubernetes/config.go => source/inspector_java_source.go} (57%)
 copy pkg/util/{kubernetes/config.go => source/inspector_kotlin.go} (57%)
 create mode 100644 pkg/util/source/inspector_xml.go
 create mode 100644 pkg/util/source/inspector_yaml_flow.go
 create mode 100644 runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/InMemoryRegistry.java
 create mode 100644 runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
 rename runtime/{camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm => camel-k-runtime-core/src/main/java/org/apache/camel/k/support}/URIResolver.java (98%)
 rename runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/{RuntimeSupport.java => ApplicationSupport.java} (72%)
 copy runtime/{camel-k-runtime-core => camel-k-runtime-yaml}/pom.xml (78%)
 create mode 100644 runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/YamlFlowLoader.java
 copy runtime/{camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/dsl/RegistryConfiguration.kt => camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Endpoint.java} (62%)
 copy runtime/{camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/dsl/RegistryConfiguration.kt => camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Flow.java} (76%)
 copy runtime/{camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/dsl/ContextConfiguration.kt => camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Step.java} (56%)
 copy runtime/{camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/dsl/RegistryConfiguration.kt => camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/StepHandler.java} (71%)
 copy runtime/{camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/dsl/RegistryConfiguration.kt => camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/handler/EndpointHandler.java} (59%)
 copy runtime/{camel-k-runtime-jvm/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml => camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/loader/yaml-flow} (94%)
 copy runtime/{camel-k-runtime-jvm/src/main/resources/META-INF/services/org/apache/camel/k/loader/java-class => camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/yaml/flow/endpoint} (92%)
 create mode 100644 runtime/camel-k-runtime-yaml/src/test/java/org/apache/camel/k/yaml/RoutesLoaderTest.java
 copy runtime/{camel-k-runtime-kotlin => camel-k-runtime-yaml}/src/test/resources/log4j2-test.xml (100%)
 create mode 100644 runtime/camel-k-runtime-yaml/src/test/resources/routes.flow


[camel-k] 03/04: chore(lint): fix findings

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

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

commit 0572cd206e41933bdefedcaf2f42bf8e5a7b6631
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Dec 20 22:17:34 2018 +0100

    chore(lint): fix findings
---
 pkg/builder/builder_steps.go      | 4 +++-
 pkg/client/cmd/install.go         | 4 +++-
 pkg/install/operator.go           | 1 +
 pkg/trait/dependencies.go         | 7 ++++---
 pkg/util/kubernetes/collection.go | 3 ++-
 pkg/util/kubernetes/loader.go     | 1 +
 pkg/util/maven/maven_project.go   | 7 ++++---
 7 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/pkg/builder/builder_steps.go b/pkg/builder/builder_steps.go
index e55f8cc..ffe7137 100644
--- a/pkg/builder/builder_steps.go
+++ b/pkg/builder/builder_steps.go
@@ -250,7 +250,9 @@ func ListPublishedImages(context *Context) ([]PublishedImage, error) {
 		return nil, err
 	}
 	images := make([]PublishedImage, 0)
-	for _, ctx := range list.Items {
+	for _, item := range list.Items {
+		ctx := item
+
 		if ctx.Status.Phase != v1alpha1.IntegrationContextPhaseReady || ctx.Labels == nil {
 			continue
 		}
diff --git a/pkg/client/cmd/install.go b/pkg/client/cmd/install.go
index 142f521..6abe4bc 100644
--- a/pkg/client/cmd/install.go
+++ b/pkg/client/cmd/install.go
@@ -83,7 +83,9 @@ func (o *installCmdOptions) install(cmd *cobra.Command, args []string) error {
 		err := install.SetupClusterwideResourcesOrCollect(collection)
 		if err != nil && k8serrors.IsForbidden(err) {
 			fmt.Println("Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles: ", err)
-			return errors.New("please login as cluster-admin and execute \"kamel install --cluster-setup\" to install cluster-wide resources (one-time operation)")
+
+			meg := `please login as cluster-admin and execute "kamel install --cluster-setup" to install cluster-wide resources (one-time operation)`
+			return errors.New(meg)
 		} else if err != nil {
 			return err
 		}
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 3088df3..a35c344 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -96,6 +96,7 @@ func Platform(namespace string, registry string, organization string, pushSecret
 }
 
 // PlatformOrCollect --
+// nolint: lll
 func PlatformOrCollect(namespace string, registry string, organization string, pushSecret string, collection *kubernetes.Collection) (*v1alpha1.IntegrationPlatform, error) {
 	if err := waitForPlatformCRDAvailable(namespace, 25*time.Second); err != nil {
 		return nil, err
diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go
index 3593dde..eddee8b 100644
--- a/pkg/trait/dependencies.go
+++ b/pkg/trait/dependencies.go
@@ -49,11 +49,12 @@ func (t *dependenciesTrait) Apply(e *Environment) error {
 	for _, s := range e.Integration.Spec.Sources {
 		meta := metadata.Extract(s)
 
-		if meta.Language == v1alpha1.LanguageGroovy {
+		switch meta.Language {
+		case v1alpha1.LanguageGroovy:
 			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:groovy")
-		} else if meta.Language == v1alpha1.LanguageKotlin {
+		case v1alpha1.LanguageKotlin:
 			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:kotlin")
-		} else if meta.Language == v1alpha1.LanguageYamlFlow {
+		case v1alpha1.LanguageYamlFlow:
 			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:yaml")
 		}
 
diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go
index 54b340b..6d7e1ce 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -23,6 +23,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
@@ -52,7 +53,7 @@ func (c *Collection) Items() []runtime.Object {
 func (c *Collection) AsKubernetesList() *corev1.List {
 	lst := corev1.List{
 		TypeMeta: metav1.TypeMeta{
-			Kind: "List",
+			Kind:       "List",
 			APIVersion: "v1",
 		},
 		Items: make([]runtime.RawExtension, 0, len(c.items)),
diff --git a/pkg/util/kubernetes/loader.go b/pkg/util/kubernetes/loader.go
index cd830da..19085f1 100644
--- a/pkg/util/kubernetes/loader.go
+++ b/pkg/util/kubernetes/loader.go
@@ -19,6 +19,7 @@ package kubernetes
 
 import (
 	"encoding/json"
+
 	"github.com/operator-framework/operator-sdk/pkg/util/k8sutil"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
diff --git a/pkg/util/maven/maven_project.go b/pkg/util/maven/maven_project.go
index 925d6e5..e965677 100644
--- a/pkg/util/maven/maven_project.go
+++ b/pkg/util/maven/maven_project.go
@@ -151,11 +151,12 @@ func NewRepository(repo string) Repository {
 		r.URL = repo[:idx]
 
 		for _, attribute := range strings.Split(repo[idx+1:], "@") {
-			if attribute == "snapshots" {
+			switch {
+			case attribute == "snapshots":
 				r.Snapshots.Enabled = true
-			} else if attribute == "noreleases" {
+			case attribute == "noreleases":
 				r.Releases.Enabled = false
-			} else if strings.HasPrefix(attribute, "id=") {
+			case strings.HasPrefix(attribute, "id="):
 				r.ID = attribute[3:]
 			}
 		}


[camel-k] 02/04: create knative context #183

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

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

commit 9b7ce11cb795169a732162f16a58ac4e43522954
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Dec 20 21:48:50 2018 +0100

    create knative context #183
---
 ...w.yaml => platform-integration-context-knative.yaml} |  5 +++--
 deploy/resources.go                                     | 17 +++++++++--------
 pkg/builder/builder_steps.go                            |  8 ++++++++
 pkg/builder/springboot/generator.go                     |  8 ++++++++
 pkg/metadata/dependencies.go                            |  3 +++
 pkg/stub/action/platform/create.go                      | 16 ++++++++++++++--
 pkg/util/envvar/envvar.go                               |  3 ++-
 pkg/util/maven/maven_project.go                         |  4 +++-
 8 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/deploy/platform-integration-context-flow.yaml b/deploy/platform-integration-context-knative.yaml
similarity index 85%
rename from deploy/platform-integration-context-flow.yaml
rename to deploy/platform-integration-context-knative.yaml
index 054f3c1..895ef39 100644
--- a/deploy/platform-integration-context-flow.yaml
+++ b/deploy/platform-integration-context-knative.yaml
@@ -1,7 +1,7 @@
 apiVersion: camel.apache.org/v1alpha1
 kind: IntegrationContext
 metadata:
-  name: flow
+  name: knative
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
@@ -11,4 +11,5 @@ spec:
   dependencies:
     - runtime:jvm
     - runtime:yaml
-    - camel:core
\ No newline at end of file
+    - camel:core
+    - camel-k:knative
\ No newline at end of file
diff --git a/deploy/resources.go b/deploy/resources.go
index 6ceed46..7f6a768 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -2723,12 +2723,12 @@ spec:
     camelVersion: "2.23.0"
 
 `
-	Resources["platform-integration-context-flow.yaml"] =
+	Resources["platform-integration-context-groovy.yaml"] =
 		`
 apiVersion: camel.apache.org/v1alpha1
 kind: IntegrationContext
 metadata:
-  name: flow
+  name: groovy
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
@@ -2737,15 +2737,15 @@ metadata:
 spec:
   dependencies:
     - runtime:jvm
-    - runtime:yaml
+    - runtime:groovy
     - camel:core
 `
-	Resources["platform-integration-context-groovy.yaml"] =
+	Resources["platform-integration-context-jvm.yaml"] =
 		`
 apiVersion: camel.apache.org/v1alpha1
 kind: IntegrationContext
 metadata:
-  name: groovy
+  name: jvm
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
@@ -2754,15 +2754,14 @@ metadata:
 spec:
   dependencies:
     - runtime:jvm
-    - runtime:groovy
     - camel:core
 `
-	Resources["platform-integration-context-jvm.yaml"] =
+	Resources["platform-integration-context-knative.yaml"] =
 		`
 apiVersion: camel.apache.org/v1alpha1
 kind: IntegrationContext
 metadata:
-  name: jvm
+  name: knative
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
@@ -2771,7 +2770,9 @@ metadata:
 spec:
   dependencies:
     - runtime:jvm
+    - runtime:yaml
     - camel:core
+    - camel-k:knative
 `
 	Resources["platform-integration-context-kotlin.yaml"] =
 		`
diff --git a/pkg/builder/builder_steps.go b/pkg/builder/builder_steps.go
index b50fb9b..e55f8cc 100644
--- a/pkg/builder/builder_steps.go
+++ b/pkg/builder/builder_steps.go
@@ -81,6 +81,14 @@ func GenerateProject(ctx *Context) error {
 			}
 
 			deps.AddGAV("org.apache.camel", artifactID, "")
+		case strings.HasPrefix(d, "camel-k:"):
+			artifactID := strings.TrimPrefix(d, "camel-k:")
+
+			if !strings.HasPrefix(artifactID, "camel-") {
+				artifactID = "camel-" + artifactID
+			}
+
+			deps.AddGAV("org.apache.camel.k", artifactID, version.Version)
 		case strings.HasPrefix(d, "mvn:"):
 			mid := strings.TrimPrefix(d, "mvn:")
 			gav := strings.Replace(mid, "/", ":", -1)
diff --git a/pkg/builder/springboot/generator.go b/pkg/builder/springboot/generator.go
index a50e04f..e107a51 100644
--- a/pkg/builder/springboot/generator.go
+++ b/pkg/builder/springboot/generator.go
@@ -125,6 +125,14 @@ func GenerateProject(ctx *builder.Context) error {
 					},
 				},
 			})
+		case strings.HasPrefix(d, "camel-k:"):
+			artifactID := strings.TrimPrefix(d, "camel-k:")
+
+			if !strings.HasPrefix(artifactID, "camel-") {
+				artifactID = "camel-" + artifactID
+			}
+
+			deps.AddGAV("org.apache.camel.k", artifactID, version.Version)
 		case strings.HasPrefix(d, "mvn:"):
 			mid := strings.TrimPrefix(d, "mvn:")
 			gav := strings.Replace(mid, "/", ":", -1)
diff --git a/pkg/metadata/dependencies.go b/pkg/metadata/dependencies.go
index c2bcc83..f70efdd 100644
--- a/pkg/metadata/dependencies.go
+++ b/pkg/metadata/dependencies.go
@@ -68,6 +68,9 @@ func decodeComponent(uri string) string {
 		if component.GroupID == "org.apache.camel" && strings.HasPrefix(artifactID, "camel-") {
 			return "camel:" + artifactID[6:]
 		}
+		if component.GroupID == "org.apache.camel.k" && strings.HasPrefix(artifactID, "camel-") {
+			return "camel-k:" + artifactID[6:]
+		}
 		return "mvn:" + component.GroupID + ":" + artifactID + ":" + component.Version
 	}
 	return ""
diff --git a/pkg/stub/action/platform/create.go b/pkg/stub/action/platform/create.go
index 5ab81ae..c5b70fd 100644
--- a/pkg/stub/action/platform/create.go
+++ b/pkg/stub/action/platform/create.go
@@ -28,10 +28,13 @@ var resources = []string{
 	"platform-integration-context-jvm.yaml",
 	"platform-integration-context-groovy.yaml",
 	"platform-integration-context-kotlin.yaml",
-	"platform-integration-context-yaml.yaml",
 	"platform-integration-context-spring-boot.yaml",
 }
 
+var knativeResources = []string{
+	"platform-integration-context-knative.yaml",
+}
+
 // NewCreateAction returns a action that creates resources needed by the platform
 func NewCreateAction() Action {
 	return &createAction{}
@@ -49,14 +52,23 @@ func (action *createAction) CanHandle(platform *v1alpha1.IntegrationPlatform) bo
 }
 
 func (action *createAction) Handle(platform *v1alpha1.IntegrationPlatform) error {
+	logrus.Info("Installing platform resources")
 	err := install.Resources(platform.Namespace, resources...)
 	if err != nil {
 		return err
 	}
 
+	if platform.Spec.Profile == v1alpha1.TraitProfileKnative {
+		logrus.Info("Installing knative resources")
+		err := install.Resources(platform.Namespace, knativeResources...)
+		if err != nil {
+			return err
+		}
+	}
+
 	target := platform.DeepCopy()
-	logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseStarting)
 	target.Status.Phase = v1alpha1.IntegrationPlatformPhaseStarting
+	logrus.Info("Platform ", target.Name, " transitioning to state ", target.Status.Phase)
 
 	return sdk.Update(target)
 }
diff --git a/pkg/util/envvar/envvar.go b/pkg/util/envvar/envvar.go
index d8739cf..ae0b998 100644
--- a/pkg/util/envvar/envvar.go
+++ b/pkg/util/envvar/envvar.go
@@ -35,7 +35,8 @@ func Remove(vars *[]v1.EnvVar, name string) {
 	v := *vars
 	for i := 0; i < len(v); i++ {
 		if v[i].Name == name {
-			*vars = append(v[:i], v[i+1:]...)
+			v = append(v[:i], v[i+1:]...)
+			*vars = v
 			return
 		}
 	}
diff --git a/pkg/util/maven/maven_project.go b/pkg/util/maven/maven_project.go
index cba227b..925d6e5 100644
--- a/pkg/util/maven/maven_project.go
+++ b/pkg/util/maven/maven_project.go
@@ -225,7 +225,9 @@ func (m Properties) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
 	}
 
 	for k, v := range m {
-		e.Encode(propertiesEntry{XMLName: xml.Name{Local: k}, Value: v})
+		if err := e.Encode(propertiesEntry{XMLName: xml.Name{Local: k}, Value: v}); err != nil {
+			return err
+		}
 	}
 
 	return e.EncodeToken(start.End())


[camel-k] 01/04: add support for a simple yaml flow

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

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

commit e48fe409aad3aaafc650484a5ab66ffa6175d82c
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Dec 20 12:04:06 2018 +0100

    add support for a simple yaml flow
---
 ...yaml => platform-integration-context-flow.yaml} |   6 +-
 deploy/platform-integration-context-groovy.yaml    |   2 +-
 deploy/platform-integration-context-jvm.yaml       |   2 +-
 deploy/platform-integration-context-kotlin.yaml    |   2 +-
 .../platform-integration-context-spring-boot.yaml  |   2 +-
 deploy/resources.go                                |  25 ++-
 examples/routes.flow                               |   5 +
 pkg/apis/camel/v1alpha1/types.go                   |  13 ++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   |  37 ++++
 pkg/metadata/languages.go                          |   3 +-
 pkg/metadata/metadata.go                           |   6 +-
 pkg/metadata/metadata_uri_test.go                  |  28 +++
 pkg/metadata/uris.go                               | 196 ++++++++++++++++++---
 pkg/stub/action/platform/create.go                 |   1 +
 pkg/trait/dependencies.go                          |   2 +
 .../java/org/apache/camel/k/InMemoryRegistry.java  |  81 +++++++++
 .../src/main/java/org/apache/camel/k/Language.java |   4 +
 .../org/apache/camel/k/support/RuntimeSupport.java | 108 ++++++++++++
 .../org/apache/camel/k/support}/URIResolver.java   |   2 +-
 .../camel/k/groovy/GroovyRoutesLoader.groovy       |   2 +-
 .../org/apache/camel/k/groovy/LoaderTest.groovy    |   6 +-
 .../java/org/apache/camel/k/jvm/Application.java   |   7 +-
 ...RuntimeSupport.java => ApplicationSupport.java} |  86 +--------
 .../main/java/org/apache/camel/k/jvm/Runtime.java  |  70 +-------
 .../camel/k/jvm/loader/JavaScriptLoader.java       |   2 +-
 .../camel/k/jvm/loader/JavaSourceLoader.java       |   2 +-
 .../org/apache/camel/k/jvm/loader/XmlLoader.java   |   2 +-
 .../org/apache/camel/k/jvm/PropertiesTest.java     |   2 +-
 .../org/apache/camel/k/jvm/RoutesLoadersTest.java  |  18 +-
 .../java/org/apache/camel/k/jvm/RuntimeTest.java   |   2 +-
 .../apache/camel/k/kotlin/KotlinRoutesLoader.kt    |   2 +-
 .../kotlin/org/apache/camel/k/kotlin/LoaderTest.kt |   6 +-
 .../apache/camel/k/spring/boot/Application.java    |   7 +-
 runtime/camel-k-runtime-yaml/pom.xml               |  88 +++++++++
 .../org/apache/camel/k/yaml/YamlFlowLoader.java    | 104 +++++++++++
 .../org/apache/camel/k/yaml/model/Endpoint.java    |  46 +++++
 .../java/org/apache/camel/k/yaml/model/Flow.java   |  31 ++++
 .../java/org/apache/camel/k/yaml/model/Step.java   |  38 ++++
 .../org/apache/camel/k/yaml/model/StepHandler.java |  30 ++++
 .../k/yaml/model/handler/EndpointHandler.java      |  36 ++++
 .../services/org/apache/camel/k/loader/yaml-flow   |  18 ++
 .../services/org/apache/camel/k/yaml/flow/endpoint |  18 ++
 .../org/apache/camel/k/yaml/RoutesLoaderTest.java  |  51 ++++++
 .../src/test/resources/log4j2-test.xml             |  17 ++
 .../src/test/resources/routes.flow                 |   5 +
 runtime/pom.xml                                    |   1 +
 46 files changed, 1001 insertions(+), 221 deletions(-)

diff --git a/deploy/platform-integration-context-groovy.yaml b/deploy/platform-integration-context-flow.yaml
similarity index 68%
copy from deploy/platform-integration-context-groovy.yaml
copy to deploy/platform-integration-context-flow.yaml
index 31aaeff..054f3c1 100644
--- a/deploy/platform-integration-context-groovy.yaml
+++ b/deploy/platform-integration-context-flow.yaml
@@ -1,14 +1,14 @@
 apiVersion: camel.apache.org/v1alpha1
 kind: IntegrationContext
 metadata:
-  name: groovy
+  name: flow
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: core
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
     - runtime:jvm
-    - runtime:groovy
+    - runtime:yaml
     - camel:core
\ No newline at end of file
diff --git a/deploy/platform-integration-context-groovy.yaml b/deploy/platform-integration-context-groovy.yaml
index 31aaeff..5265f51 100644
--- a/deploy/platform-integration-context-groovy.yaml
+++ b/deploy/platform-integration-context-groovy.yaml
@@ -5,7 +5,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: core
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-context-jvm.yaml b/deploy/platform-integration-context-jvm.yaml
index 28e8ff5..acaf7c3 100644
--- a/deploy/platform-integration-context-jvm.yaml
+++ b/deploy/platform-integration-context-jvm.yaml
@@ -5,7 +5,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-context-kotlin.yaml b/deploy/platform-integration-context-kotlin.yaml
index 822b4a4..8eb5836 100644
--- a/deploy/platform-integration-context-kotlin.yaml
+++ b/deploy/platform-integration-context-kotlin.yaml
@@ -5,7 +5,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-context-spring-boot.yaml b/deploy/platform-integration-context-spring-boot.yaml
index e52d9f7..5b86911 100644
--- a/deploy/platform-integration-context-spring-boot.yaml
+++ b/deploy/platform-integration-context-spring-boot.yaml
@@ -5,7 +5,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
diff --git a/deploy/resources.go b/deploy/resources.go
index 5ebc74b..6ceed46 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -2723,6 +2723,23 @@ spec:
     camelVersion: "2.23.0"
 
 `
+	Resources["platform-integration-context-flow.yaml"] =
+		`
+apiVersion: camel.apache.org/v1alpha1
+kind: IntegrationContext
+metadata:
+  name: flow
+  labels:
+    app: "camel-k"
+    camel.apache.org/context.created.by.kind: Operator
+    camel.apache.org/context.created.by.name: camel-k-operator
+    camel.apache.org/context.type: platform
+spec:
+  dependencies:
+    - runtime:jvm
+    - runtime:yaml
+    - camel:core
+`
 	Resources["platform-integration-context-groovy.yaml"] =
 		`
 apiVersion: camel.apache.org/v1alpha1
@@ -2732,7 +2749,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: core
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
@@ -2749,7 +2766,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
@@ -2765,7 +2782,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
@@ -2782,7 +2799,7 @@ metadata:
   labels:
     app: "camel-k"
     camel.apache.org/context.created.by.kind: Operator
-    camel.apache.org/context.created.by.name: jvm
+    camel.apache.org/context.created.by.name: camel-k-operator
     camel.apache.org/context.type: platform
 spec:
   dependencies:
diff --git a/examples/routes.flow b/examples/routes.flow
new file mode 100644
index 0000000..ea69305
--- /dev/null
+++ b/examples/routes.flow
@@ -0,0 +1,5 @@
+- steps:
+    - kind: "endpoint"
+      uri: "timer:tick?period=5s"
+    - kind: "endpoint"
+      uri: "log:info"
diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go
index 0627da1..ef4dcc0 100644
--- a/pkg/apis/camel/v1alpha1/types.go
+++ b/pkg/apis/camel/v1alpha1/types.go
@@ -133,6 +133,8 @@ const (
 	LanguageXML Language = "xml"
 	// LanguageKotlin --
 	LanguageKotlin Language = "kts"
+	// LanguageYamlFlow --
+	LanguageYamlFlow Language = "flow"
 )
 
 // A IntegrationTraitSpec contains the configuration of a trait
@@ -355,3 +357,14 @@ type Artifact struct {
 func (in *Artifact) String() string {
 	return in.ID
 }
+
+// Flow --
+type Flow struct {
+	Steps []Step `json:"steps"`
+}
+
+// Step --
+type Step struct {
+	Kind string `json:"kind"`
+	URI  string `json:"uri"`
+}
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index c61ab94..85e3be8 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -74,6 +74,27 @@ func (in *DataSpec) DeepCopy() *DataSpec {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Flow) DeepCopyInto(out *Flow) {
+	*out = *in
+	if in.Steps != nil {
+		in, out := &in.Steps, &out.Steps
+		*out = make([]Step, len(*in))
+		copy(*out, *in)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Flow.
+func (in *Flow) DeepCopy() *Flow {
+	if in == nil {
+		return nil
+	}
+	out := new(Flow)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Integration) DeepCopyInto(out *Integration) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
@@ -501,3 +522,19 @@ func (in *SourceSpec) DeepCopy() *SourceSpec {
 	in.DeepCopyInto(out)
 	return out
 }
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Step) DeepCopyInto(out *Step) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Step.
+func (in *Step) DeepCopy() *Step {
+	if in == nil {
+		return nil
+	}
+	out := new(Step)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/pkg/metadata/languages.go b/pkg/metadata/languages.go
index 2d0d2da..55389dc 100644
--- a/pkg/metadata/languages.go
+++ b/pkg/metadata/languages.go
@@ -34,7 +34,8 @@ func discoverLanguage(source v1alpha1.SourceSpec) v1alpha1.Language {
 		v1alpha1.LanguageJavaScript,
 		v1alpha1.LanguageGroovy,
 		v1alpha1.LanguageJavaScript,
-		v1alpha1.LanguageKotlin} {
+		v1alpha1.LanguageKotlin,
+		v1alpha1.LanguageYamlFlow} {
 
 		if strings.HasSuffix(source.Name, "."+string(l)) {
 			return l
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index 30263e9..a696f99 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -70,8 +70,10 @@ func merge(m1 IntegrationMetadata, m2 IntegrationMetadata) IntegrationMetadata {
 // Extract returns metadata information from the source code
 func Extract(source v1alpha1.SourceSpec) IntegrationMetadata {
 	language := discoverLanguage(source)
-	fromURIs := discoverFromURIs(source, language)
-	toURIs := discoverToURIs(source, language)
+	// TODO: handle error
+	fromURIs, _ := GetInspectorForLanguage(language).FromURIs(source)
+	// TODO:: handle error
+	toURIs, _ := GetInspectorForLanguage(language).ToURIs(source)
 	dependencies := discoverDependencies(source, fromURIs, toURIs)
 	requiresHTTPService := requiresHTTPService(source, fromURIs)
 	passiveEndpoints := hasOnlyPassiveEndpoints(source, fromURIs)
diff --git a/pkg/metadata/metadata_uri_test.go b/pkg/metadata/metadata_uri_test.go
index 9dc26d4..6c13658 100644
--- a/pkg/metadata/metadata_uri_test.go
+++ b/pkg/metadata/metadata_uri_test.go
@@ -227,3 +227,31 @@ func TestJavascript1(t *testing.T) {
 	assert.Contains(t, metadata.ToURIs, "uri:%s") // resolution not supported yet
 	assert.Len(t, metadata.ToURIs, 4)
 }
+
+const yamlFlow = `
+- steps:
+  - kind: "endpoint"
+    uri: "timer:tick"
+  - kind: "endpoint"
+    uri: "log:info"
+`
+
+func TestJYamlFlow(t *testing.T) {
+	source := v1alpha1.SourceSpec{
+		DataSpec: v1alpha1.DataSpec{
+			Name:    "test",
+			Content: yamlFlow,
+		},
+		Language: v1alpha1.LanguageYamlFlow,
+	}
+
+	metadata := Extract(source)
+
+	assert.NotEmpty(t, metadata.FromURIs)
+	assert.Contains(t, metadata.FromURIs, "timer:tick")
+	assert.Len(t, metadata.FromURIs, 1)
+
+	assert.NotEmpty(t, metadata.ToURIs)
+	assert.Contains(t, metadata.ToURIs, "log:info")
+	assert.Len(t, metadata.ToURIs, 1)
+}
diff --git a/pkg/metadata/uris.go b/pkg/metadata/uris.go
index 0c08f9a..c267cfa 100644
--- a/pkg/metadata/uris.go
+++ b/pkg/metadata/uris.go
@@ -21,6 +21,7 @@ import (
 	"regexp"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	yaml "gopkg.in/yaml.v2"
 )
 
 var (
@@ -37,48 +38,185 @@ var (
 	xmlTagToD        = regexp.MustCompile(`<\s*toD\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`)
 )
 
-// discoverFromURIs returns all uris used in a from clause
-func discoverFromURIs(source v1alpha1.SourceSpec, language v1alpha1.Language) []string {
-	fromRegexps := getFromRegexpsForLanguage(language)
-	return findAllDistinctStringSubmatch(source.Content, fromRegexps...)
+// LanguageInspector --
+type LanguageInspector interface {
+	FromURIs(v1alpha1.SourceSpec) ([]string, error)
+	ToURIs(v1alpha1.SourceSpec) ([]string, error)
 }
 
-// discoverToURIs returns all uris used in a to clause
-func discoverToURIs(source v1alpha1.SourceSpec, language v1alpha1.Language) []string {
-	toRegexps := getToRegexpsForLanguage(language)
-	return findAllDistinctStringSubmatch(source.Content, toRegexps...)
+type languageInspector struct {
+	from func(v1alpha1.SourceSpec) ([]string, error)
+	to   func(v1alpha1.SourceSpec) ([]string, error)
 }
 
-func getFromRegexpsForLanguage(language v1alpha1.Language) []*regexp.Regexp {
-	switch language {
-	case v1alpha1.LanguageJavaSource:
-		return []*regexp.Regexp{doubleQuotedFrom}
-	case v1alpha1.LanguageXML:
-		return []*regexp.Regexp{xmlTagFrom}
-	case v1alpha1.LanguageGroovy:
-		return []*regexp.Regexp{singleQuotedFrom, doubleQuotedFrom}
-	case v1alpha1.LanguageJavaScript:
-		return []*regexp.Regexp{singleQuotedFrom, doubleQuotedFrom}
-	case v1alpha1.LanguageKotlin:
-		return []*regexp.Regexp{doubleQuotedFrom}
-	}
-	return []*regexp.Regexp{}
+func (i languageInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	return i.from(source)
+}
+func (i languageInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	return i.to(source)
 }
 
-func getToRegexpsForLanguage(language v1alpha1.Language) []*regexp.Regexp {
+// GetInspectorForLanguage --
+func GetInspectorForLanguage(language v1alpha1.Language) LanguageInspector {
 	switch language {
 	case v1alpha1.LanguageJavaSource:
-		return []*regexp.Regexp{doubleQuotedTo, doubleQuotedToD, doubleQuotedToF}
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					doubleQuotedFrom,
+				)
+
+				return answer, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					doubleQuotedTo,
+					doubleQuotedToD,
+					doubleQuotedToF,
+				)
+
+				return answer, nil
+			},
+		}
 	case v1alpha1.LanguageXML:
-		return []*regexp.Regexp{xmlTagTo, xmlTagToD}
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					xmlTagFrom,
+				)
+
+				return answer, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					xmlTagTo,
+					xmlTagToD,
+				)
+
+				return answer, nil
+			},
+		}
 	case v1alpha1.LanguageGroovy:
-		return []*regexp.Regexp{singleQuotedTo, doubleQuotedTo, singleQuotedToD, doubleQuotedToD, singleQuotedToF, doubleQuotedToF}
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					singleQuotedFrom,
+					doubleQuotedFrom,
+				)
+
+				return answer, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					singleQuotedTo,
+					doubleQuotedTo,
+					singleQuotedToD,
+					doubleQuotedToD,
+					singleQuotedToF,
+					doubleQuotedToF,
+				)
+
+				return answer, nil
+			},
+		}
 	case v1alpha1.LanguageJavaScript:
-		return []*regexp.Regexp{singleQuotedTo, doubleQuotedTo, singleQuotedToD, doubleQuotedToD, singleQuotedToF, doubleQuotedToF}
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					singleQuotedFrom,
+					doubleQuotedFrom,
+				)
+
+				return answer, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					singleQuotedTo,
+					doubleQuotedTo,
+					singleQuotedToD,
+					doubleQuotedToD,
+					singleQuotedToF,
+					doubleQuotedToF,
+				)
+
+				return answer, nil
+			},
+		}
 	case v1alpha1.LanguageKotlin:
-		return []*regexp.Regexp{doubleQuotedTo, doubleQuotedToD, doubleQuotedToF}
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					doubleQuotedFrom,
+				)
+
+				return answer, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				answer := findAllDistinctStringSubmatch(
+					source.Content,
+					doubleQuotedTo,
+					doubleQuotedToD,
+					doubleQuotedToF,
+				)
+
+				return answer, nil
+			},
+		}
+	case v1alpha1.LanguageYamlFlow:
+		var flows []v1alpha1.Flow
+
+		return &languageInspector{
+			from: func(source v1alpha1.SourceSpec) ([]string, error) {
+				if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
+					return []string{}, nil
+				}
+
+				uris := make([]string, 0)
+
+				for _, flow := range flows {
+					if flow.Steps[0].URI != "" {
+						uris = append(uris, flow.Steps[0].URI)
+					}
+
+				}
+				return uris, nil
+			},
+			to: func(source v1alpha1.SourceSpec) ([]string, error) {
+				if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
+					return []string{}, nil
+				}
+
+				uris := make([]string, 0)
+
+				for _, flow := range flows {
+					for i := 1; i < len(flow.Steps); i++ {
+						if flow.Steps[i].URI != "" {
+							uris = append(uris, flow.Steps[i].URI)
+						}
+					}
+				}
+
+				return uris, nil
+			},
+		}
+	}
+	return &languageInspector{
+		from: func(source v1alpha1.SourceSpec) ([]string, error) {
+			return []string{}, nil
+		},
+		to: func(source v1alpha1.SourceSpec) ([]string, error) {
+			return []string{}, nil
+		},
 	}
-	return []*regexp.Regexp{}
 }
 
 func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string {
diff --git a/pkg/stub/action/platform/create.go b/pkg/stub/action/platform/create.go
index 5f8ea2f..5ab81ae 100644
--- a/pkg/stub/action/platform/create.go
+++ b/pkg/stub/action/platform/create.go
@@ -28,6 +28,7 @@ var resources = []string{
 	"platform-integration-context-jvm.yaml",
 	"platform-integration-context-groovy.yaml",
 	"platform-integration-context-kotlin.yaml",
+	"platform-integration-context-yaml.yaml",
 	"platform-integration-context-spring-boot.yaml",
 }
 
diff --git a/pkg/trait/dependencies.go b/pkg/trait/dependencies.go
index ccbc41b..3593dde 100644
--- a/pkg/trait/dependencies.go
+++ b/pkg/trait/dependencies.go
@@ -53,6 +53,8 @@ func (t *dependenciesTrait) Apply(e *Environment) error {
 			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:groovy")
 		} else if meta.Language == v1alpha1.LanguageKotlin {
 			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:kotlin")
+		} else if meta.Language == v1alpha1.LanguageYamlFlow {
+			util.StringSliceUniqueAdd(&e.Integration.Spec.Dependencies, "runtime:yaml")
 		}
 
 		// jvm runtime and camel-core required by default
diff --git a/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/InMemoryRegistry.java b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/InMemoryRegistry.java
new file mode 100644
index 0000000..203a03c
--- /dev/null
+++ b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/InMemoryRegistry.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Collectors;
+
+import org.apache.camel.NoSuchBeanException;
+
+public final class InMemoryRegistry implements RuntimeRegistry {
+    private final ConcurrentMap<String, Object> registry;
+
+    public InMemoryRegistry() {
+        this.registry = new ConcurrentHashMap<>();
+    }
+
+    public void bind(String name, Object bean) {
+        this.registry.put(name, bean);
+    }
+
+    @Override
+    public Object lookupByName(String name) {
+        return registry.get(name);
+    }
+
+    @Override
+    public <T> T lookupByNameAndType(String name, Class<T> type) {
+        final Object answer = lookupByName(name);
+
+        if (answer != null) {
+            try {
+                return type.cast(answer);
+            } catch (Throwable t) {
+                throw new NoSuchBeanException(
+                    name,
+                    "Found bean: " + name + " in RuntimeRegistry: " + this + " of type: " + answer.getClass().getName() + " expected type was: " + type,
+                    t
+                );
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public <T> Map<String, T> findByTypeWithName(Class<T> type) {
+        final Map<String, T> result = new HashMap<>();
+
+        registry.entrySet().stream()
+            .filter(entry -> type.isInstance(entry.getValue()))
+            .forEach(entry -> result.put(entry.getKey(), type.cast(entry.getValue())));
+
+        return result;
+    }
+
+    @Override
+    public <T> Set<T> findByType(Class<T> type) {
+        return registry.values().stream()
+            .filter(type::isInstance)
+            .map(type::cast)
+            .collect(Collectors.toSet());
+    }
+}
diff --git a/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/Language.java b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/Language.java
index 1f7f9a3..5fb0194 100644
--- a/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/Language.java
+++ b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/Language.java
@@ -48,6 +48,10 @@ public enum Language {
         "xml",
         Collections.singletonList("xml"),
         Collections.singletonList("xml")),
+    YamlFlow(
+        "yaml-flow",
+        Arrays.asList("yaml-flow", "flow"),
+        Collections.singletonList("flow")),
     Kotlin(
         "kotlin",
         Arrays.asList("kotlin", "kts"),
diff --git a/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
new file mode 100644
index 0000000..9c92e5e
--- /dev/null
+++ b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.support;
+
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NoFactoryAvailableException;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.k.Constants;
+import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.RuntimeTrait;
+import org.apache.camel.k.Source;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.util.IntrospectionSupport;
+
+
+public final class RuntimeSupport {
+    private RuntimeSupport() {
+    }
+
+    public static void configureContext(CamelContext context) {
+        try {
+            FactoryFinder finder = context.getFactoryFinder(Constants.RUNTIME_TRAIT_RESOURCE_PATH);
+            String traitIDs = System.getenv().getOrDefault(Constants.ENV_CAMEL_K_TRAITS, "");
+
+            for (String traitId: traitIDs.split(",", -1)) {
+                RuntimeTrait trait = (RuntimeTrait)finder.newInstance(traitId);
+
+                bindProperties(context, trait, "trait." + traitId);
+
+                trait.apply(context);
+            }
+        } catch (NoFactoryAvailableException e) {
+            // ignored
+        }
+
+        context.getRegistry().findByType(RuntimeTrait.class).forEach(
+            customizer -> {
+                customizer.apply(context);
+            }
+        );
+    }
+
+    public static void bindProperties(CamelContext context, Object target, String prefix) {
+        final PropertiesComponent component = context.getComponent("properties", PropertiesComponent.class);
+        final Properties properties = component.getInitialProperties();
+
+        if (properties == null) {
+            throw new IllegalStateException("PropertiesComponent has no properties");
+        }
+
+        bindProperties(properties, target, prefix);
+    }
+
+    public static void bindProperties(Properties properties, Object target, String prefix) {
+        properties.entrySet().stream()
+            .filter(entry -> entry.getKey() instanceof String)
+            .filter(entry -> entry.getValue() != null)
+            .filter(entry -> ((String)entry.getKey()).startsWith(prefix))
+            .forEach(entry -> {
+                    final String key = ((String)entry.getKey()).substring(prefix.length());
+                    final Object val = entry.getValue();
+
+                    try {
+                        IntrospectionSupport.setProperty(target, key, val, false);
+                    } catch (Exception ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+            );
+    }
+
+    public static RoutesLoader loaderFor(CamelContext context, Source source) {
+        return  context.getRegistry().findByType(RoutesLoader.class).stream()
+            .filter(rl -> rl.getSupportedLanguages().contains(source.getLanguage()))
+            .findFirst()
+            .orElseGet(() -> lookupLoaderFromResource(context, source));
+    }
+
+    public static RoutesLoader lookupLoaderFromResource(CamelContext context, Source source) {
+        final FactoryFinder finder;
+        final RoutesLoader loader;
+
+        try {
+            finder = context.getFactoryFinder(Constants.ROUTES_LOADER_RESOURCE_PATH);
+            loader = (RoutesLoader)finder.newInstance(source.getLanguage().getId());
+        } catch (NoFactoryAvailableException e) {
+            throw new IllegalArgumentException("Unable to find loader for: " + source, e);
+        }
+
+        return loader;
+    }
+}
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/URIResolver.java b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/URIResolver.java
similarity index 98%
rename from runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/URIResolver.java
rename to runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/URIResolver.java
index 30bee2e..3b20602 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/URIResolver.java
+++ b/runtime/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/URIResolver.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.k.jvm;
+package org.apache.camel.k.support;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
diff --git a/runtime/camel-k-runtime-groovy/src/main/groovy/org/apache/camel/k/groovy/GroovyRoutesLoader.groovy b/runtime/camel-k-runtime-groovy/src/main/groovy/org/apache/camel/k/groovy/GroovyRoutesLoader.groovy
index bb081d4..8493c48 100644
--- a/runtime/camel-k-runtime-groovy/src/main/groovy/org/apache/camel/k/groovy/GroovyRoutesLoader.groovy
+++ b/runtime/camel-k-runtime-groovy/src/main/groovy/org/apache/camel/k/groovy/GroovyRoutesLoader.groovy
@@ -22,8 +22,8 @@ import org.apache.camel.k.Language
 import org.apache.camel.k.RoutesLoader
 import org.apache.camel.k.RuntimeRegistry
 import org.apache.camel.k.Source
+import org.apache.camel.k.support.URIResolver
 import org.apache.camel.k.groovy.dsl.IntegrationConfiguration
-import org.apache.camel.k.jvm.*
 import org.codehaus.groovy.control.CompilerConfiguration
 
 class GroovyRoutesLoader implements RoutesLoader {
diff --git a/runtime/camel-k-runtime-groovy/src/test/groovy/org/apache/camel/k/groovy/LoaderTest.groovy b/runtime/camel-k-runtime-groovy/src/test/groovy/org/apache/camel/k/groovy/LoaderTest.groovy
index 87ce859..72fe2db 100644
--- a/runtime/camel-k-runtime-groovy/src/test/groovy/org/apache/camel/k/groovy/LoaderTest.groovy
+++ b/runtime/camel-k-runtime-groovy/src/test/groovy/org/apache/camel/k/groovy/LoaderTest.groovy
@@ -17,9 +17,9 @@
 package org.apache.camel.k.groovy
 
 import org.apache.camel.impl.DefaultCamelContext
-import org.apache.camel.k.jvm.Runtime
-import org.apache.camel.k.jvm.RuntimeSupport
+import org.apache.camel.k.InMemoryRegistry
 import org.apache.camel.k.Source
+import org.apache.camel.k.support.RuntimeSupport
 import org.apache.camel.model.ToDefinition
 import spock.lang.Specification
 
@@ -31,7 +31,7 @@ class LoaderTest extends Specification {
 
         when:
             def loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source)
-            def builder = loader.load(new Runtime.Registry(), source)
+            def builder = loader.load(new InMemoryRegistry(), source)
 
         then:
             loader instanceof GroovyRoutesLoader
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java
index b98c95b..82ad36a 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java
@@ -19,6 +19,7 @@ package org.apache.camel.k.jvm;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.k.Constants;
+import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.main.MainListenerSupport;
 import org.apache.camel.support.LifecycleStrategySupport;
 import org.apache.camel.util.ObjectHelper;
@@ -33,14 +34,14 @@ public class Application {
         //
         // We now support setting the logging level only
         //
-        RuntimeSupport.configureLogging();
+        ApplicationSupport.configureLogging();
 
         //
         // Install a custom protocol handler to support discovering resources
         // from the platform i.e. in knative, resources are provided through
         // env var as it is not possible to mount config maps / secrets.
         //
-        RuntimeSupport.configureStreamHandler();
+        ApplicationSupport.configureStreamHandler();
     }
 
     // *******************************
@@ -57,7 +58,7 @@ public class Application {
         }
 
         Runtime runtime = new Runtime();
-        runtime.setProperties(RuntimeSupport.loadProperties());
+        runtime.setProperties(ApplicationSupport.loadProperties());
         runtime.load(routes.split(",", -1));
         runtime.addMainListener(new ComponentPropertiesBinder());
         runtime.run();
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/ApplicationSupport.java
similarity index 72%
rename from runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java
rename to runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/ApplicationSupport.java
index 60d1cf9..97d6cea 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/ApplicationSupport.java
@@ -38,15 +38,8 @@ import java.util.Objects;
 import java.util.Properties;
 import java.util.zip.GZIPInputStream;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.NoFactoryAvailableException;
-import org.apache.camel.component.properties.PropertiesComponent;
 import org.apache.camel.k.Constants;
-import org.apache.camel.k.RoutesLoader;
-import org.apache.camel.k.RuntimeTrait;
-import org.apache.camel.k.Source;
-import org.apache.camel.spi.FactoryFinder;
-import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.k.support.URIResolver;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.commons.io.FilenameUtils;
@@ -57,8 +50,8 @@ import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 
 
-public final class RuntimeSupport {
-    private RuntimeSupport() {
+public final class ApplicationSupport {
+    private ApplicationSupport() {
     }
 
     public static Properties loadProperties() {
@@ -122,29 +115,6 @@ public final class RuntimeSupport {
         return properties;
     }
 
-    public static void configureContext(CamelContext context) {
-        try {
-            FactoryFinder finder = context.getFactoryFinder(Constants.RUNTIME_TRAIT_RESOURCE_PATH);
-            String traitIDs = System.getenv().getOrDefault(Constants.ENV_CAMEL_K_TRAITS, "");
-
-            for (String traitId: traitIDs.split(",", -1)) {
-                RuntimeTrait trait = (RuntimeTrait)finder.newInstance(traitId);
-
-                bindProperties(context, trait, "trait." + traitId);
-
-                trait.apply(context);
-            }
-        } catch (NoFactoryAvailableException e) {
-            // ignored
-        }
-
-        context.getRegistry().findByType(RuntimeTrait.class).forEach(
-            customizer -> {
-                customizer.apply(context);
-            }
-        );
-    }
-
     public static void configureLogging() {
         final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         final Properties properties = loadProperties();
@@ -166,56 +136,6 @@ public final class RuntimeSupport {
         );
     }
 
-    public static void bindProperties(CamelContext context, Object target, String prefix) {
-        final PropertiesComponent component = context.getComponent("properties", PropertiesComponent.class);
-        final Properties properties = component.getInitialProperties();
-
-        if (properties == null) {
-            throw new IllegalStateException("PropertiesComponent has no properties");
-        }
-
-        bindProperties(properties, target, prefix);
-    }
-
-    public static void bindProperties(Properties properties, Object target, String prefix) {
-        properties.entrySet().stream()
-            .filter(entry -> entry.getKey() instanceof String)
-            .filter(entry -> entry.getValue() != null)
-            .filter(entry -> ((String)entry.getKey()).startsWith(prefix))
-            .forEach(entry -> {
-                    final String key = ((String)entry.getKey()).substring(prefix.length());
-                    final Object val = entry.getValue();
-
-                    try {
-                        IntrospectionSupport.setProperty(target, key, val, false);
-                    } catch (Exception ex) {
-                        throw new RuntimeException(ex);
-                    }
-                }
-            );
-    }
-
-    public static RoutesLoader loaderFor(CamelContext context, Source source) {
-        return  context.getRegistry().findByType(RoutesLoader.class).stream()
-            .filter(rl -> rl.getSupportedLanguages().contains(source.getLanguage()))
-            .findFirst()
-            .orElseGet(() -> lookupLoaderFromResource(context, source));
-    }
-
-    public static RoutesLoader lookupLoaderFromResource(CamelContext context, Source source) {
-        final FactoryFinder finder;
-        final RoutesLoader loader;
-
-        try {
-            finder = context.getFactoryFinder(Constants.ROUTES_LOADER_RESOURCE_PATH);
-            loader = (RoutesLoader)finder.newInstance(source.getLanguage().getId());
-        } catch (NoFactoryAvailableException e) {
-            throw new IllegalArgumentException("Unable to find loader for: " + source, e);
-        }
-
-        return loader;
-    }
-
     public static void configureStreamHandler() {
         URL.setURLStreamHandlerFactory(protocol -> "platform".equals(protocol) ? new PlatformStreamHandler() : null);
     }
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Runtime.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Runtime.java
index 4d5adb5..a68545d 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Runtime.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Runtime.java
@@ -16,24 +16,22 @@
  */
 package org.apache.camel.k.jvm;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.properties.PropertiesComponent;
 import org.apache.camel.impl.CompositeRegistry;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.k.InMemoryRegistry;
 import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.main.MainSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,7 +44,7 @@ public final class Runtime extends MainSupport {
 
     public Runtime() {
         this.contextMap = new ConcurrentHashMap<>();
-        this.registry = new Registry();
+        this.registry = new InMemoryRegistry();
     }
 
     public void load(String[] routes) throws Exception {
@@ -126,66 +124,4 @@ public final class Runtime extends MainSupport {
             getCamelContexts().get(0).stop();
         }
     }
-
-    // ********************************
-    //
-    // Registry
-    //
-    // ********************************
-
-    public static final class Registry implements RuntimeRegistry {
-        private final ConcurrentMap<String, Object> registry;
-
-        public Registry() {
-            this.registry = new ConcurrentHashMap<>();
-        }
-
-        public void bind(String name, Object bean) {
-            this.registry.put(name, bean);
-        }
-
-        @Override
-        public Object lookupByName(String name) {
-            return registry.get(name);
-        }
-
-        @Override
-        public <T> T lookupByNameAndType(String name, Class<T> type) {
-            final Object answer = lookupByName(name);
-
-            if (answer != null) {
-                try {
-                    return type.cast(answer);
-                } catch (Throwable t) {
-                    throw new NoSuchBeanException(
-                        name,
-                        "Found bean: " + name + " in RuntimeRegistry: " + this + " of type: " + answer.getClass().getName() + " expected type was: " + type,
-                        t
-                    );
-                }
-            }
-
-            return null;
-        }
-
-        @Override
-        public <T> Map<String, T> findByTypeWithName(Class<T> type) {
-            final Map<String, T> result = new HashMap<>();
-
-            registry.entrySet().stream()
-                .filter(entry -> type.isInstance(entry.getValue()))
-                .forEach(entry -> result.put(entry.getKey(), type.cast(entry.getValue())));
-
-            return result;
-        }
-
-        @Override
-        public <T> Set<T> findByType(Class<T> type) {
-            return registry.values().stream()
-                .filter(type::isInstance)
-                .map(type::cast)
-                .collect(Collectors.toSet());
-        }
-    }
-
 }
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaScriptLoader.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaScriptLoader.java
index 650a4d1..ca05c10 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaScriptLoader.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaScriptLoader.java
@@ -17,7 +17,7 @@ import org.apache.camel.k.Language;
 import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Source;
-import org.apache.camel.k.jvm.URIResolver;
+import org.apache.camel.k.support.URIResolver;
 import org.apache.camel.k.jvm.dsl.Components;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.rest.RestConfigurationDefinition;
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaSourceLoader.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaSourceLoader.java
index 767a6d4..bdcb6e3 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaSourceLoader.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/JavaSourceLoader.java
@@ -10,7 +10,7 @@ import org.apache.camel.k.Language;
 import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Source;
-import org.apache.camel.k.jvm.URIResolver;
+import org.apache.camel.k.support.URIResolver;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joor.Reflect;
diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/XmlLoader.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/XmlLoader.java
index 7532f14..113104d 100644
--- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/XmlLoader.java
+++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/loader/XmlLoader.java
@@ -10,7 +10,7 @@ import org.apache.camel.k.Language;
 import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Source;
-import org.apache.camel.k.jvm.URIResolver;
+import org.apache.camel.k.support.URIResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/PropertiesTest.java b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/PropertiesTest.java
index 43e0d9c..808664c 100644
--- a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/PropertiesTest.java
+++ b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/PropertiesTest.java
@@ -30,7 +30,7 @@ public class PropertiesTest {
 
     @Test
     public void testLoadProperties() throws Exception {
-        Properties properties = RuntimeSupport.loadProperties("src/test/resources/conf.properties", "src/test/resources/conf.d");
+        Properties properties = ApplicationSupport.loadProperties("src/test/resources/conf.properties", "src/test/resources/conf.d");
 
         Runtime runtime = new Runtime();
         runtime.setProperties(properties);
diff --git a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
index 88c29f9..64394c7 100644
--- a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
+++ b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.k.InMemoryRegistry;
 import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Source;
@@ -27,6 +28,7 @@ import org.apache.camel.k.jvm.loader.JavaClassLoader;
 import org.apache.camel.k.jvm.loader.JavaScriptLoader;
 import org.apache.camel.k.jvm.loader.JavaSourceLoader;
 import org.apache.camel.k.jvm.loader.XmlLoader;
+import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.model.ProcessDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.SetBodyDefinition;
@@ -41,7 +43,7 @@ public class RoutesLoadersTest {
     @Test
     public void testLoaderFromRegistry() throws Exception {
         RoutesLoader myLoader = new JavaClassLoader();
-        RuntimeRegistry registry = new Runtime.Registry();
+        RuntimeRegistry registry = new InMemoryRegistry();
         registry.bind("my-loader", myLoader);
 
         Source source = Source.create("classpath:" + MyRoutes.class.getName() + ".class");
@@ -55,7 +57,7 @@ public class RoutesLoadersTest {
     public void testLoadClass() throws Exception {
         Source source = Source.create("classpath:" + MyRoutes.class.getName() + ".class");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaClassLoader.class);
         assertThat(builder).isNotNull();
@@ -72,7 +74,7 @@ public class RoutesLoadersTest {
     public void testLoadJava() throws Exception {
         Source source = Source.create("classpath:MyRoutes.java");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaSourceLoader.class);
         assertThat(builder).isNotNull();
@@ -89,7 +91,7 @@ public class RoutesLoadersTest {
     public void testLoadJavaWithNestedClass() throws Exception {
         Source source = Source.create("classpath:MyRoutesWithNestedClass.java");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaSourceLoader.class);
         assertThat(builder).isNotNull();
@@ -108,7 +110,7 @@ public class RoutesLoadersTest {
     public void testLoadJavaScript() throws Exception {
         Source source = Source.create("classpath:routes.js");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaScriptLoader.class);
         assertThat(builder).isNotNull();
@@ -125,7 +127,7 @@ public class RoutesLoadersTest {
     public void testLoadCompressedRoute() throws Exception {
         Source source = Source.create("classpath:routes-compressed.js.gz.b64?language=js&compression=true");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaScriptLoader.class);
         assertThat(builder).isNotNull();
@@ -142,7 +144,7 @@ public class RoutesLoadersTest {
     public void testLoadJavaScriptWithCustomExtension() throws Exception {
         Source source = Source.create("classpath:routes.mytype?language=js");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(JavaScriptLoader.class);
         assertThat(builder).isNotNull();
@@ -159,7 +161,7 @@ public class RoutesLoadersTest {
     public void testLoadXml() throws Exception {
         Source source = Source.create("classpath:routes.xml");
         RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new Runtime.Registry(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
 
         assertThat(loader).isInstanceOf(XmlLoader.class);
         assertThat(builder).isNotNull();
diff --git a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java
index e434c26..533c353 100644
--- a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java
+++ b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java
@@ -56,7 +56,7 @@ public class RuntimeTest {
 
     @Test
     void testLoadResource() throws Exception {
-        RuntimeSupport.configureStreamHandler();
+        ApplicationSupport.configureStreamHandler();
 
         CamelContext context = new Runtime().getCamelContext();
 
diff --git a/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt b/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt
index d72bb60..efd01ee 100644
--- a/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt
+++ b/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt
@@ -21,8 +21,8 @@ import org.apache.camel.k.Language
 import org.apache.camel.k.RoutesLoader
 import org.apache.camel.k.RuntimeRegistry
 import org.apache.camel.k.Source
-import org.apache.camel.k.jvm.URIResolver
 import org.apache.camel.k.kotlin.dsl.IntegrationConfiguration
+import org.apache.camel.k.support.URIResolver
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import java.io.File
diff --git a/runtime/camel-k-runtime-kotlin/src/test/kotlin/org/apache/camel/k/kotlin/LoaderTest.kt b/runtime/camel-k-runtime-kotlin/src/test/kotlin/org/apache/camel/k/kotlin/LoaderTest.kt
index be4dced..8b09000 100644
--- a/runtime/camel-k-runtime-kotlin/src/test/kotlin/org/apache/camel/k/kotlin/LoaderTest.kt
+++ b/runtime/camel-k-runtime-kotlin/src/test/kotlin/org/apache/camel/k/kotlin/LoaderTest.kt
@@ -17,9 +17,9 @@
 package org.apache.camel.k.kotlin
 
 import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.k.InMemoryRegistry
 import org.apache.camel.k.Source
-import org.apache.camel.k.jvm.Runtime
-import org.apache.camel.k.jvm.RuntimeSupport
+import org.apache.camel.k.support.RuntimeSupport
 import org.apache.camel.model.ProcessDefinition
 import org.apache.camel.model.ToDefinition
 import org.assertj.core.api.Assertions.assertThat
@@ -31,7 +31,7 @@ class LoaderTest {
     fun `load route from classpath`() {
         var source = Source.create("classpath:routes.kts")
         val loader = RuntimeSupport.loaderFor(DefaultCamelContext(), source)
-        val builder = loader.load(Runtime.Registry(), source)
+        val builder = loader.load(InMemoryRegistry(), source)
 
         assertThat(loader).isInstanceOf(KotlinRoutesLoader::class.java)
         assertThat(builder).isNotNull
diff --git a/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java b/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java
index a6fbb5a..91839aa 100644
--- a/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java
+++ b/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java
@@ -25,8 +25,9 @@ import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.k.RuntimeRegistry;
 import org.apache.camel.k.Constants;
 import org.apache.camel.k.RoutesLoader;
-import org.apache.camel.k.jvm.RuntimeSupport;
+import org.apache.camel.k.jvm.ApplicationSupport;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.spring.boot.CamelContextConfiguration;
 import org.apache.camel.util.ObjectHelper;
@@ -48,7 +49,7 @@ public class Application {
         // from the platform i.e. in knative, resources are provided through
         // env var as it is not possible to mount config maps / secrets.
         //
-        RuntimeSupport.configureStreamHandler();
+        ApplicationSupport.configureStreamHandler();
     }
 
     public static void main(String[] args) {
@@ -64,7 +65,7 @@ public class Application {
     @Bean
     public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
         // load properties using default behaviour
-        final Properties properties = RuntimeSupport.loadProperties();
+        final Properties properties = ApplicationSupport.loadProperties();
 
         // set spring boot specific properties
         properties.put("camel.springboot.main-run-controller", "true");
diff --git a/runtime/camel-k-runtime-yaml/pom.xml b/runtime/camel-k-runtime-yaml/pom.xml
new file mode 100644
index 0000000..0e94a55
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.camel.k</groupId>
+        <artifactId>camel-k-runtime-parent</artifactId>
+        <version>0.1.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-k-runtime-yaml</artifactId>
+
+    <dependencies>
+
+        <!-- ****************************** -->
+        <!--                                -->
+        <!-- RUNTIME                        -->
+        <!--                                -->
+        <!-- ****************************** -->
+
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-runtime-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-runtime-jvm</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-yaml</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+
+        <!-- ****************************** -->
+        <!--                                -->
+        <!-- TESTS                          -->
+        <!--                                -->
+        <!-- ****************************** -->
+
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit-jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit-jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/YamlFlowLoader.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/YamlFlowLoader.java
new file mode 100644
index 0000000..d5b5a37
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/YamlFlowLoader.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.k.Language;
+import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.RuntimeRegistry;
+import org.apache.camel.k.Source;
+import org.apache.camel.k.support.URIResolver;
+import org.apache.camel.k.yaml.model.Endpoint;
+import org.apache.camel.k.yaml.model.Flow;
+import org.apache.camel.k.yaml.model.Step;
+import org.apache.camel.k.yaml.model.StepHandler;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.FactoryFinder;
+
+public class YamlFlowLoader implements RoutesLoader {
+    private final ObjectMapper mapper;
+
+    public YamlFlowLoader() {
+        YAMLFactory yamlFactory = new YAMLFactory()
+            .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true)
+            .configure(YAMLGenerator.Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS, true)
+            .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false);
+
+        this.mapper = new ObjectMapper(yamlFactory)
+            .setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
+            .enable(SerializationFeature.INDENT_OUTPUT);
+
+        mapper.registerSubtypes(new NamedType(Endpoint.class, Endpoint.KIND));
+    }
+
+    @Override
+    public List<Language> getSupportedLanguages() {
+        return Collections.singletonList(Language.YamlFlow);
+    }
+
+    @SuppressWarnings("uncheked")
+    @Override
+    public RouteBuilder load(RuntimeRegistry registry, Source source) throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                try (InputStream is = URIResolver.resolve(getContext(), source)) {
+                    for (Flow flow: mapper.readValue(is, Flow[].class)) {
+                        final List<Step> steps = flow.getSteps();
+                        final int size = steps.size();
+                        final FactoryFinder finder = getContext().getFactoryFinder(Step.RESOURCE_PATH);
+
+                        ProcessorDefinition<?> definition = null;
+
+                        for (int i = 0; i < size; i++) {
+                            Step step = steps.get(i);
+
+                            if (i == 0) {
+                                // force the cast so it will fail at runtime
+                                // if the step is not of the right type
+                                definition = from(((Endpoint) step).getUri());
+
+                                continue;
+                            }
+
+                            if (definition == null) {
+                                throw new IllegalStateException("No route definition");
+                            }
+
+                            StepHandler<Step> handler = (StepHandler<Step>)finder.newInstance(step.getKind());
+                            if (handler == null) {
+                                throw new IllegalStateException("No handler for step with kind: " + step.getKind());
+                            }
+
+                            definition = handler.handle(step, definition);
+                        }
+                    }
+                }
+            }
+        };
+    }
+}
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Endpoint.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Endpoint.java
new file mode 100644
index 0000000..6ad07ee
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Endpoint.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml.model;
+
+public class Endpoint extends Step {
+    public static final String KIND = "endpoint";
+
+    private String uri;
+
+    public Endpoint() {
+        super(KIND);
+    }
+
+    public Endpoint(String uri) {
+        super(KIND);
+
+        this.uri = uri;
+    }
+
+    @Override
+    public String toString() {
+        return "Endpoint: " + uri;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+}
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Flow.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Flow.java
new file mode 100644
index 0000000..89031dd
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Flow.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml.model;
+
+import java.util.List;
+
+public class Flow {
+    private List<Step> steps;
+
+    public List<Step> getSteps() {
+        return steps;
+    }
+
+    public void setSteps(List<Step> steps) {
+        this.steps = steps;
+    }
+}
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Step.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Step.java
new file mode 100644
index 0000000..f2e8a2e
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/Step.java
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "kind")
+public abstract class Step {
+    public static final String RESOURCE_PATH = "META-INF/services/org/apache/camel/k/yaml/flow/";
+
+    private final String kind;
+
+    public Step(String kind) {
+        this.kind = kind;
+    }
+
+    @JsonIgnore
+    public String getKind() {
+        return kind;
+    }
+}
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/StepHandler.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/StepHandler.java
new file mode 100644
index 0000000..8a26030
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/StepHandler.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml.model;
+
+import org.apache.camel.model.ProcessorDefinition;
+
+@FunctionalInterface
+public interface StepHandler<T extends Step> {
+
+    /**
+     * @param step the step
+     * @param route the handler
+     * @return
+     */
+    ProcessorDefinition<?> handle(T step, ProcessorDefinition<?> route);
+}
diff --git a/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/handler/EndpointHandler.java b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/handler/EndpointHandler.java
new file mode 100644
index 0000000..25b80b5
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/java/org/apache/camel/k/yaml/model/handler/EndpointHandler.java
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml.model.handler;
+
+import org.apache.camel.k.yaml.model.Endpoint;
+import org.apache.camel.k.yaml.model.StepHandler;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.util.ObjectHelper;
+
+public class EndpointHandler implements StepHandler<Endpoint> {
+    @Override
+    public ProcessorDefinition<?> handle(Endpoint step, ProcessorDefinition<?> route) {
+        String uri = step.getUri();
+
+        if (!ObjectHelper.isEmpty(uri)) {
+            route = route.to(uri);
+        }
+
+        return route;
+    }
+}
+
diff --git a/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/loader/yaml-flow b/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/loader/yaml-flow
new file mode 100644
index 0000000..242f874
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/loader/yaml-flow
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.k.yaml.YamlFlowLoader
\ No newline at end of file
diff --git a/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/yaml/flow/endpoint b/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/yaml/flow/endpoint
new file mode 100644
index 0000000..6af1c19
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/main/resources/META-INF/services/org/apache/camel/k/yaml/flow/endpoint
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.k.yaml.model.handler.EndpointHandler
\ No newline at end of file
diff --git a/runtime/camel-k-runtime-yaml/src/test/java/org/apache/camel/k/yaml/RoutesLoaderTest.java b/runtime/camel-k-runtime-yaml/src/test/java/org/apache/camel/k/yaml/RoutesLoaderTest.java
new file mode 100644
index 0000000..1035306
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/test/java/org/apache/camel/k/yaml/RoutesLoaderTest.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.yaml;
+
+import java.util.List;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Source;
+import org.apache.camel.k.InMemoryRegistry;
+import org.apache.camel.k.support.RuntimeSupport;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RoutesLoaderTest {
+
+    @Test
+    public void testLoadYamlFlow() throws Exception {
+        Source source = Source.create("classpath:routes.flow");
+        RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source);
+        RouteBuilder builder = loader.load(new InMemoryRegistry(), source);
+
+        assertThat(loader).isInstanceOf(YamlFlowLoader.class);
+        assertThat(builder).isNotNull();
+
+        builder.configure();
+
+        List<RouteDefinition> routes = builder.getRouteCollection().getRoutes();
+        assertThat(routes).hasSize(1);
+        assertThat(routes.get(0).getInputs().get(0).getEndpointUri()).isEqualTo("timer:tick");
+        assertThat(routes.get(0).getOutputs().get(0)).isInstanceOf(ToDefinition.class);
+    }
+}
diff --git a/runtime/camel-k-runtime-yaml/src/test/resources/log4j2-test.xml b/runtime/camel-k-runtime-yaml/src/test/resources/log4j2-test.xml
new file mode 100644
index 0000000..a505fd9
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/test/resources/log4j2-test.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="INFO">
+  <Appenders>
+    <Console name="STDOUT" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%t|%c{1} - %msg%n"/>
+    </Console>
+    <Null name="NONE"/>
+  </Appenders>
+
+  <Loggers>
+    <Root level="INFO">
+      <!-- <AppenderRef ref="STDOUT"/> -->
+      <AppenderRef ref="NONE"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
\ No newline at end of file
diff --git a/runtime/camel-k-runtime-yaml/src/test/resources/routes.flow b/runtime/camel-k-runtime-yaml/src/test/resources/routes.flow
new file mode 100644
index 0000000..1964535
--- /dev/null
+++ b/runtime/camel-k-runtime-yaml/src/test/resources/routes.flow
@@ -0,0 +1,5 @@
+- steps:
+  - kind: "endpoint"
+    uri: "timer:tick"
+  - kind: "endpoint"
+    uri: "log:info"
\ No newline at end of file
diff --git a/runtime/pom.xml b/runtime/pom.xml
index 014e40b..29a6846 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -98,6 +98,7 @@
         <module>camel-k-runtime-jvm</module>
         <module>camel-k-runtime-groovy</module>
         <module>camel-k-runtime-kotlin</module>
+        <module>camel-k-runtime-yaml</module>
         <module>camel-k-runtime-spring-boot</module>
         <module>catalog-builder</module>
         <module>dependency-lister</module>


[camel-k] 04/04: inspect xml source code using streaming parser

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

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

commit 11ca9c6b20ea200a5179db649190b0c7ae930382
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Dec 20 23:02:31 2018 +0100

    inspect xml source code using streaming parser
---
 pkg/metadata/metadata.go                 |   5 +-
 pkg/metadata/uris.go                     | 239 -------------------------------
 pkg/util/source/inspector.go             |  89 ++++++++++++
 pkg/util/source/inspector_groovy.go      |  50 +++++++
 pkg/util/source/inspector_java_script.go |  50 +++++++
 pkg/util/source/inspector_java_source.go |  46 ++++++
 pkg/util/source/inspector_kotlin.go      |  46 ++++++
 pkg/util/source/inspector_xml.go         |  89 ++++++++++++
 pkg/util/source/inspector_yaml_flow.go   |  67 +++++++++
 9 files changed, 440 insertions(+), 241 deletions(-)

diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index a696f99..4f7d980 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -21,6 +21,7 @@ import (
 	"sort"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	src "github.com/apache/camel-k/pkg/util/source"
 )
 
 // ExtractAll returns metadata information from all listed source codes
@@ -71,9 +72,9 @@ func merge(m1 IntegrationMetadata, m2 IntegrationMetadata) IntegrationMetadata {
 func Extract(source v1alpha1.SourceSpec) IntegrationMetadata {
 	language := discoverLanguage(source)
 	// TODO: handle error
-	fromURIs, _ := GetInspectorForLanguage(language).FromURIs(source)
+	fromURIs, _ := src.InspectorForLanguage(language).FromURIs(source)
 	// TODO:: handle error
-	toURIs, _ := GetInspectorForLanguage(language).ToURIs(source)
+	toURIs, _ := src.InspectorForLanguage(language).ToURIs(source)
 	dependencies := discoverDependencies(source, fromURIs, toURIs)
 	requiresHTTPService := requiresHTTPService(source, fromURIs)
 	passiveEndpoints := hasOnlyPassiveEndpoints(source, fromURIs)
diff --git a/pkg/metadata/uris.go b/pkg/metadata/uris.go
deleted file mode 100644
index c267cfa..0000000
--- a/pkg/metadata/uris.go
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package metadata
-
-import (
-	"regexp"
-
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	yaml "gopkg.in/yaml.v2"
-)
-
-var (
-	singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
-	doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
-	singleQuotedTo   = regexp.MustCompile(`\.to\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
-	singleQuotedToD  = regexp.MustCompile(`\.toD\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
-	singleQuotedToF  = regexp.MustCompile(`\.toF\s*\(\s*'([a-z0-9-]+:[^']+)'[^)]*\)`)
-	doubleQuotedTo   = regexp.MustCompile(`\.to\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
-	doubleQuotedToD  = regexp.MustCompile(`\.toD\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
-	doubleQuotedToF  = regexp.MustCompile(`\.toF\s*\(\s*"([a-z0-9-]+:[^"]+)"[^)]*\)`)
-	xmlTagFrom       = regexp.MustCompile(`<\s*from\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`)
-	xmlTagTo         = regexp.MustCompile(`<\s*to\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`)
-	xmlTagToD        = regexp.MustCompile(`<\s*toD\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`)
-)
-
-// LanguageInspector --
-type LanguageInspector interface {
-	FromURIs(v1alpha1.SourceSpec) ([]string, error)
-	ToURIs(v1alpha1.SourceSpec) ([]string, error)
-}
-
-type languageInspector struct {
-	from func(v1alpha1.SourceSpec) ([]string, error)
-	to   func(v1alpha1.SourceSpec) ([]string, error)
-}
-
-func (i languageInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
-	return i.from(source)
-}
-func (i languageInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
-	return i.to(source)
-}
-
-// GetInspectorForLanguage --
-func GetInspectorForLanguage(language v1alpha1.Language) LanguageInspector {
-	switch language {
-	case v1alpha1.LanguageJavaSource:
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					doubleQuotedFrom,
-				)
-
-				return answer, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					doubleQuotedTo,
-					doubleQuotedToD,
-					doubleQuotedToF,
-				)
-
-				return answer, nil
-			},
-		}
-	case v1alpha1.LanguageXML:
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					xmlTagFrom,
-				)
-
-				return answer, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					xmlTagTo,
-					xmlTagToD,
-				)
-
-				return answer, nil
-			},
-		}
-	case v1alpha1.LanguageGroovy:
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					singleQuotedFrom,
-					doubleQuotedFrom,
-				)
-
-				return answer, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					singleQuotedTo,
-					doubleQuotedTo,
-					singleQuotedToD,
-					doubleQuotedToD,
-					singleQuotedToF,
-					doubleQuotedToF,
-				)
-
-				return answer, nil
-			},
-		}
-	case v1alpha1.LanguageJavaScript:
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					singleQuotedFrom,
-					doubleQuotedFrom,
-				)
-
-				return answer, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					singleQuotedTo,
-					doubleQuotedTo,
-					singleQuotedToD,
-					doubleQuotedToD,
-					singleQuotedToF,
-					doubleQuotedToF,
-				)
-
-				return answer, nil
-			},
-		}
-	case v1alpha1.LanguageKotlin:
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					doubleQuotedFrom,
-				)
-
-				return answer, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				answer := findAllDistinctStringSubmatch(
-					source.Content,
-					doubleQuotedTo,
-					doubleQuotedToD,
-					doubleQuotedToF,
-				)
-
-				return answer, nil
-			},
-		}
-	case v1alpha1.LanguageYamlFlow:
-		var flows []v1alpha1.Flow
-
-		return &languageInspector{
-			from: func(source v1alpha1.SourceSpec) ([]string, error) {
-				if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
-					return []string{}, nil
-				}
-
-				uris := make([]string, 0)
-
-				for _, flow := range flows {
-					if flow.Steps[0].URI != "" {
-						uris = append(uris, flow.Steps[0].URI)
-					}
-
-				}
-				return uris, nil
-			},
-			to: func(source v1alpha1.SourceSpec) ([]string, error) {
-				if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
-					return []string{}, nil
-				}
-
-				uris := make([]string, 0)
-
-				for _, flow := range flows {
-					for i := 1; i < len(flow.Steps); i++ {
-						if flow.Steps[i].URI != "" {
-							uris = append(uris, flow.Steps[i].URI)
-						}
-					}
-				}
-
-				return uris, nil
-			},
-		}
-	}
-	return &languageInspector{
-		from: func(source v1alpha1.SourceSpec) ([]string, error) {
-			return []string{}, nil
-		},
-		to: func(source v1alpha1.SourceSpec) ([]string, error) {
-			return []string{}, nil
-		},
-	}
-}
-
-func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string {
-	candidates := make([]string, 0)
-	alreadyFound := make(map[string]bool)
-	for _, reg := range regexps {
-		hits := reg.FindAllStringSubmatch(data, -1)
-		for _, hit := range hits {
-			if len(hit) > 1 {
-				for _, match := range hit[1:] {
-					if _, ok := alreadyFound[match]; !ok {
-						alreadyFound[match] = true
-						candidates = append(candidates, match)
-					}
-				}
-			}
-		}
-	}
-	return candidates
-}
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
new file mode 100644
index 0000000..db76c49
--- /dev/null
+++ b/pkg/util/source/inspector.go
@@ -0,0 +1,89 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import (
+	"regexp"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+var (
+	singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
+	doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
+	singleQuotedTo   = regexp.MustCompile(`\.to\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
+	singleQuotedToD  = regexp.MustCompile(`\.toD\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`)
+	singleQuotedToF  = regexp.MustCompile(`\.toF\s*\(\s*'([a-z0-9-]+:[^']+)'[^)]*\)`)
+	doubleQuotedTo   = regexp.MustCompile(`\.to\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
+	doubleQuotedToD  = regexp.MustCompile(`\.toD\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`)
+	doubleQuotedToF  = regexp.MustCompile(`\.toF\s*\(\s*"([a-z0-9-]+:[^"]+)"[^)]*\)`)
+)
+
+// Inspector --
+type Inspector interface {
+	FromURIs(v1alpha1.SourceSpec) ([]string, error)
+	ToURIs(v1alpha1.SourceSpec) ([]string, error)
+}
+
+// InspectorForLanguage --
+func InspectorForLanguage(language v1alpha1.Language) Inspector {
+	switch language {
+	case v1alpha1.LanguageJavaSource:
+		return &JavaSourceInspector{}
+	case v1alpha1.LanguageXML:
+		return &XMLInspector{}
+	case v1alpha1.LanguageGroovy:
+		return &GroovyInspector{}
+	case v1alpha1.LanguageJavaScript:
+		return &JavaScriptInspector{}
+	case v1alpha1.LanguageKotlin:
+		return &KotlinInspector{}
+	case v1alpha1.LanguageYamlFlow:
+		return &YAMLFlowInspector{}
+	}
+	return &noInspector{}
+}
+
+func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string {
+	candidates := make([]string, 0)
+	alreadyFound := make(map[string]bool)
+	for _, reg := range regexps {
+		hits := reg.FindAllStringSubmatch(data, -1)
+		for _, hit := range hits {
+			if len(hit) > 1 {
+				for _, match := range hit[1:] {
+					if _, ok := alreadyFound[match]; !ok {
+						alreadyFound[match] = true
+						candidates = append(candidates, match)
+					}
+				}
+			}
+		}
+	}
+	return candidates
+}
+
+type noInspector struct {
+}
+
+func (i noInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	return []string{}, nil
+}
+func (i noInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	return []string{}, nil
+}
diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go
new file mode 100644
index 0000000..ddcd874
--- /dev/null
+++ b/pkg/util/source/inspector_groovy.go
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
+// GroovyInspector --
+type GroovyInspector struct {
+}
+
+// FromURIs --
+func (i GroovyInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		singleQuotedFrom,
+		doubleQuotedFrom,
+	)
+
+	return answer, nil
+}
+
+// ToURIs --
+func (i GroovyInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		singleQuotedTo,
+		doubleQuotedTo,
+		singleQuotedToD,
+		doubleQuotedToD,
+		singleQuotedToF,
+		doubleQuotedToF,
+	)
+
+	return answer, nil
+}
diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go
new file mode 100644
index 0000000..913fc8d
--- /dev/null
+++ b/pkg/util/source/inspector_java_script.go
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
+// JavaScriptInspector --
+type JavaScriptInspector struct {
+}
+
+// FromURIs --
+func (i JavaScriptInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		singleQuotedFrom,
+		doubleQuotedFrom,
+	)
+
+	return answer, nil
+}
+
+// ToURIs --
+func (i JavaScriptInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		singleQuotedTo,
+		doubleQuotedTo,
+		singleQuotedToD,
+		doubleQuotedToD,
+		singleQuotedToF,
+		doubleQuotedToF,
+	)
+
+	return answer, nil
+}
diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go
new file mode 100644
index 0000000..4a22953
--- /dev/null
+++ b/pkg/util/source/inspector_java_source.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
+// JavaSourceInspector --
+type JavaSourceInspector struct {
+}
+
+// FromURIs --
+func (i JavaSourceInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		doubleQuotedFrom,
+	)
+
+	return answer, nil
+}
+
+// ToURIs --
+func (i JavaSourceInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		doubleQuotedTo,
+		doubleQuotedToD,
+		doubleQuotedToF,
+	)
+
+	return answer, nil
+}
diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go
new file mode 100644
index 0000000..111bf14
--- /dev/null
+++ b/pkg/util/source/inspector_kotlin.go
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+
+// KotlinInspector --
+type KotlinInspector struct {
+}
+
+// FromURIs --
+func (i KotlinInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		doubleQuotedFrom,
+	)
+
+	return answer, nil
+}
+
+// ToURIs --
+func (i KotlinInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	answer := findAllDistinctStringSubmatch(
+		source.Content,
+		doubleQuotedTo,
+		doubleQuotedToD,
+		doubleQuotedToF,
+	)
+
+	return answer, nil
+}
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
new file mode 100644
index 0000000..c13f1e6
--- /dev/null
+++ b/pkg/util/source/inspector_xml.go
@@ -0,0 +1,89 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import (
+	"encoding/xml"
+	"strings"
+
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+// XMLInspector --
+type XMLInspector struct {
+}
+
+// FromURIs --
+func (i XMLInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	content := strings.NewReader(source.Content)
+	decoder := xml.NewDecoder(content)
+
+	uris := make([]string, 0)
+
+	for {
+		// Read tokens from the XML document in a stream.
+		t, _ := decoder.Token()
+		if t == nil {
+			break
+		}
+
+		switch se := t.(type) {
+		case xml.StartElement:
+			switch se.Name.Local {
+			case "from", "fromF":
+				for _, a := range se.Attr {
+					if a.Name.Local == "uri" {
+						uris = append(uris, a.Value)
+					}
+				}
+			}
+		}
+	}
+
+	return uris, nil
+}
+
+// ToURIs --
+func (i XMLInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	content := strings.NewReader(source.Content)
+	decoder := xml.NewDecoder(content)
+
+	uris := make([]string, 0)
+
+	for {
+		// Read tokens from the XML document in a stream.
+		t, _ := decoder.Token()
+		if t == nil {
+			break
+		}
+
+		switch se := t.(type) {
+		case xml.StartElement:
+			switch se.Name.Local {
+			case "to", "toD", "toF":
+				for _, a := range se.Attr {
+					if a.Name.Local == "uri" {
+						uris = append(uris, a.Value)
+					}
+				}
+			}
+		}
+	}
+
+	return uris, nil
+}
diff --git a/pkg/util/source/inspector_yaml_flow.go b/pkg/util/source/inspector_yaml_flow.go
new file mode 100644
index 0000000..e677b4d
--- /dev/null
+++ b/pkg/util/source/inspector_yaml_flow.go
@@ -0,0 +1,67 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package source
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	yaml "gopkg.in/yaml.v2"
+)
+
+// YAMLFlowInspector --
+type YAMLFlowInspector struct {
+}
+
+// FromURIs --
+func (i YAMLFlowInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	var flows []v1alpha1.Flow
+
+	if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
+		return []string{}, nil
+	}
+
+	uris := make([]string, 0)
+
+	for _, flow := range flows {
+		if flow.Steps[0].URI != "" {
+			uris = append(uris, flow.Steps[0].URI)
+		}
+
+	}
+	return uris, nil
+}
+
+// ToURIs --
+func (i YAMLFlowInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) {
+	var flows []v1alpha1.Flow
+
+	if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil {
+		return []string{}, nil
+	}
+
+	uris := make([]string, 0)
+
+	for _, flow := range flows {
+		for i := 1; i < len(flow.Steps); i++ {
+			if flow.Steps[i].URI != "" {
+				uris = append(uris, flow.Steps[i].URI)
+			}
+		}
+	}
+
+	return uris, nil
+}