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 <lburgazz...@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>