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:54 UTC
[camel-k] 01/04: add support for a simple yaml flow
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>