This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit ccb89aa0a1a413ffc3dacaed3af1a0c0ab089c3b Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Dec 7 14:48:55 2021 +0100 CAMEL-17261: camel-yaml-dsl - Add support for loading Camel K KameletBinding file. --- .../DeadLetterChannelBuilderConfigurer.java | 145 +++++++++++++++++++++ .../DefaultErrorHandlerBuilderConfigurer.java | 145 +++++++++++++++++++++ ...g.apache.camel.builder.DeadLetterChannelBuilder | 2 + ...apache.camel.builder.DefaultErrorHandlerBuilder | 2 + .../camel/builder/DeadLetterChannelBuilder.java | 2 + .../camel/builder/DefaultErrorHandlerBuilder.java | 2 + .../modules/ROOT/pages/camel-jbang.adoc | 36 +++++ .../camel-yaml-dsl/src/main/docs/yaml-dsl.adoc | 51 ++++++++ .../camel/dsl/yaml/YamlRoutesBuilderLoader.java | 41 ++++-- .../camel/dsl/yaml/KameletBindingLoaderTest.groovy | 94 +++++++++++++ .../dsl/yaml/KameletIntegrationLoaderTest.groovy | 61 +++++++++ .../camel/dsl/yaml/support/YamlTestSupport.groovy | 10 ++ 12 files changed, 580 insertions(+), 11 deletions(-) diff --git a/core/camel-core-model/src/generated/java/org/apache/camel/builder/DeadLetterChannelBuilderConfigurer.java b/core/camel-core-model/src/generated/java/org/apache/camel/builder/DeadLetterChannelBuilderConfigurer.java new file mode 100644 index 0000000..8c62d65 --- /dev/null +++ b/core/camel-core-model/src/generated/java/org/apache/camel/builder/DeadLetterChannelBuilderConfigurer.java @@ -0,0 +1,145 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.builder; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.builder.DeadLetterChannelBuilder; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class DeadLetterChannelBuilderConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + org.apache.camel.builder.DeadLetterChannelBuilder target = (org.apache.camel.builder.DeadLetterChannelBuilder) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": target.setAsyncDelayedRedelivery(property(camelContext, boolean.class, value)); return true; + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": target.setDeadLetterHandleNewException(property(camelContext, boolean.class, value)); return true; + case "deadletteruri": + case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true; + case "executorservice": + case "ExecutorService": target.setExecutorService(property(camelContext, java.util.concurrent.ScheduledExecutorService.class, value)); return true; + case "executorserviceref": + case "ExecutorServiceRef": target.setExecutorServiceRef(property(camelContext, java.lang.String.class, value)); return true; + case "logger": + case "Logger": target.setLogger(property(camelContext, org.apache.camel.spi.CamelLogger.class, value)); return true; + case "onexceptionoccurred": + case "OnExceptionOccurred": target.setOnExceptionOccurred(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": target.setOnExceptionOccurredRef(property(camelContext, java.lang.String.class, value)); return true; + case "onpreparefailure": + case "OnPrepareFailure": target.setOnPrepareFailure(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onpreparefailureref": + case "OnPrepareFailureRef": target.setOnPrepareFailureRef(property(camelContext, java.lang.String.class, value)); return true; + case "onredelivery": + case "OnRedelivery": target.setOnRedelivery(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onredeliveryref": + case "OnRedeliveryRef": target.setOnRedeliveryRef(property(camelContext, java.lang.String.class, value)); return true; + case "redeliverypolicy": + case "RedeliveryPolicy": target.setRedeliveryPolicy(property(camelContext, org.apache.camel.processor.errorhandler.RedeliveryPolicy.class, value)); return true; + case "retrywhile": + case "RetryWhile": target.setRetryWhile(property(camelContext, org.apache.camel.Predicate.class, value)); return true; + case "retrywhileref": + case "RetryWhileRef": target.setRetryWhileRef(property(camelContext, java.lang.String.class, value)); return true; + case "useoriginalbody": + case "UseOriginalBody": target.setUseOriginalBody(property(camelContext, boolean.class, value)); return true; + case "useoriginalmessage": + case "UseOriginalMessage": target.setUseOriginalMessage(property(camelContext, boolean.class, value)); return true; + default: return false; + } + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": return boolean.class; + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": return boolean.class; + case "deadletteruri": + case "DeadLetterUri": return java.lang.String.class; + case "executorservice": + case "ExecutorService": return java.util.concurrent.ScheduledExecutorService.class; + case "executorserviceref": + case "ExecutorServiceRef": return java.lang.String.class; + case "logger": + case "Logger": return org.apache.camel.spi.CamelLogger.class; + case "onexceptionoccurred": + case "OnExceptionOccurred": return org.apache.camel.Processor.class; + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": return java.lang.String.class; + case "onpreparefailure": + case "OnPrepareFailure": return org.apache.camel.Processor.class; + case "onpreparefailureref": + case "OnPrepareFailureRef": return java.lang.String.class; + case "onredelivery": + case "OnRedelivery": return org.apache.camel.Processor.class; + case "onredeliveryref": + case "OnRedeliveryRef": return java.lang.String.class; + case "redeliverypolicy": + case "RedeliveryPolicy": return org.apache.camel.processor.errorhandler.RedeliveryPolicy.class; + case "retrywhile": + case "RetryWhile": return org.apache.camel.Predicate.class; + case "retrywhileref": + case "RetryWhileRef": return java.lang.String.class; + case "useoriginalbody": + case "UseOriginalBody": return boolean.class; + case "useoriginalmessage": + case "UseOriginalMessage": return boolean.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + org.apache.camel.builder.DeadLetterChannelBuilder target = (org.apache.camel.builder.DeadLetterChannelBuilder) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": return target.isAsyncDelayedRedelivery(); + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": return target.isDeadLetterHandleNewException(); + case "deadletteruri": + case "DeadLetterUri": return target.getDeadLetterUri(); + case "executorservice": + case "ExecutorService": return target.getExecutorService(); + case "executorserviceref": + case "ExecutorServiceRef": return target.getExecutorServiceRef(); + case "logger": + case "Logger": return target.getLogger(); + case "onexceptionoccurred": + case "OnExceptionOccurred": return target.getOnExceptionOccurred(); + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": return target.getOnExceptionOccurredRef(); + case "onpreparefailure": + case "OnPrepareFailure": return target.getOnPrepareFailure(); + case "onpreparefailureref": + case "OnPrepareFailureRef": return target.getOnPrepareFailureRef(); + case "onredelivery": + case "OnRedelivery": return target.getOnRedelivery(); + case "onredeliveryref": + case "OnRedeliveryRef": return target.getOnRedeliveryRef(); + case "redeliverypolicy": + case "RedeliveryPolicy": return target.getRedeliveryPolicy(); + case "retrywhile": + case "RetryWhile": return target.getRetryWhile(); + case "retrywhileref": + case "RetryWhileRef": return target.getRetryWhileRef(); + case "useoriginalbody": + case "UseOriginalBody": return target.isUseOriginalBody(); + case "useoriginalmessage": + case "UseOriginalMessage": return target.isUseOriginalMessage(); + default: return null; + } + } +} + diff --git a/core/camel-core-model/src/generated/java/org/apache/camel/builder/DefaultErrorHandlerBuilderConfigurer.java b/core/camel-core-model/src/generated/java/org/apache/camel/builder/DefaultErrorHandlerBuilderConfigurer.java new file mode 100644 index 0000000..cf45d98 --- /dev/null +++ b/core/camel-core-model/src/generated/java/org/apache/camel/builder/DefaultErrorHandlerBuilderConfigurer.java @@ -0,0 +1,145 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.builder; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.builder.DefaultErrorHandlerBuilder; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class DefaultErrorHandlerBuilderConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + org.apache.camel.builder.DefaultErrorHandlerBuilder target = (org.apache.camel.builder.DefaultErrorHandlerBuilder) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": target.setAsyncDelayedRedelivery(property(camelContext, boolean.class, value)); return true; + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": target.setDeadLetterHandleNewException(property(camelContext, boolean.class, value)); return true; + case "deadletteruri": + case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true; + case "executorservice": + case "ExecutorService": target.setExecutorService(property(camelContext, java.util.concurrent.ScheduledExecutorService.class, value)); return true; + case "executorserviceref": + case "ExecutorServiceRef": target.setExecutorServiceRef(property(camelContext, java.lang.String.class, value)); return true; + case "logger": + case "Logger": target.setLogger(property(camelContext, org.apache.camel.spi.CamelLogger.class, value)); return true; + case "onexceptionoccurred": + case "OnExceptionOccurred": target.setOnExceptionOccurred(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": target.setOnExceptionOccurredRef(property(camelContext, java.lang.String.class, value)); return true; + case "onpreparefailure": + case "OnPrepareFailure": target.setOnPrepareFailure(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onpreparefailureref": + case "OnPrepareFailureRef": target.setOnPrepareFailureRef(property(camelContext, java.lang.String.class, value)); return true; + case "onredelivery": + case "OnRedelivery": target.setOnRedelivery(property(camelContext, org.apache.camel.Processor.class, value)); return true; + case "onredeliveryref": + case "OnRedeliveryRef": target.setOnRedeliveryRef(property(camelContext, java.lang.String.class, value)); return true; + case "redeliverypolicy": + case "RedeliveryPolicy": target.setRedeliveryPolicy(property(camelContext, org.apache.camel.processor.errorhandler.RedeliveryPolicy.class, value)); return true; + case "retrywhile": + case "RetryWhile": target.setRetryWhile(property(camelContext, org.apache.camel.Predicate.class, value)); return true; + case "retrywhileref": + case "RetryWhileRef": target.setRetryWhileRef(property(camelContext, java.lang.String.class, value)); return true; + case "useoriginalbody": + case "UseOriginalBody": target.setUseOriginalBody(property(camelContext, boolean.class, value)); return true; + case "useoriginalmessage": + case "UseOriginalMessage": target.setUseOriginalMessage(property(camelContext, boolean.class, value)); return true; + default: return false; + } + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": return boolean.class; + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": return boolean.class; + case "deadletteruri": + case "DeadLetterUri": return java.lang.String.class; + case "executorservice": + case "ExecutorService": return java.util.concurrent.ScheduledExecutorService.class; + case "executorserviceref": + case "ExecutorServiceRef": return java.lang.String.class; + case "logger": + case "Logger": return org.apache.camel.spi.CamelLogger.class; + case "onexceptionoccurred": + case "OnExceptionOccurred": return org.apache.camel.Processor.class; + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": return java.lang.String.class; + case "onpreparefailure": + case "OnPrepareFailure": return org.apache.camel.Processor.class; + case "onpreparefailureref": + case "OnPrepareFailureRef": return java.lang.String.class; + case "onredelivery": + case "OnRedelivery": return org.apache.camel.Processor.class; + case "onredeliveryref": + case "OnRedeliveryRef": return java.lang.String.class; + case "redeliverypolicy": + case "RedeliveryPolicy": return org.apache.camel.processor.errorhandler.RedeliveryPolicy.class; + case "retrywhile": + case "RetryWhile": return org.apache.camel.Predicate.class; + case "retrywhileref": + case "RetryWhileRef": return java.lang.String.class; + case "useoriginalbody": + case "UseOriginalBody": return boolean.class; + case "useoriginalmessage": + case "UseOriginalMessage": return boolean.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + org.apache.camel.builder.DefaultErrorHandlerBuilder target = (org.apache.camel.builder.DefaultErrorHandlerBuilder) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "asyncdelayedredelivery": + case "AsyncDelayedRedelivery": return target.isAsyncDelayedRedelivery(); + case "deadletterhandlenewexception": + case "DeadLetterHandleNewException": return target.isDeadLetterHandleNewException(); + case "deadletteruri": + case "DeadLetterUri": return target.getDeadLetterUri(); + case "executorservice": + case "ExecutorService": return target.getExecutorService(); + case "executorserviceref": + case "ExecutorServiceRef": return target.getExecutorServiceRef(); + case "logger": + case "Logger": return target.getLogger(); + case "onexceptionoccurred": + case "OnExceptionOccurred": return target.getOnExceptionOccurred(); + case "onexceptionoccurredref": + case "OnExceptionOccurredRef": return target.getOnExceptionOccurredRef(); + case "onpreparefailure": + case "OnPrepareFailure": return target.getOnPrepareFailure(); + case "onpreparefailureref": + case "OnPrepareFailureRef": return target.getOnPrepareFailureRef(); + case "onredelivery": + case "OnRedelivery": return target.getOnRedelivery(); + case "onredeliveryref": + case "OnRedeliveryRef": return target.getOnRedeliveryRef(); + case "redeliverypolicy": + case "RedeliveryPolicy": return target.getRedeliveryPolicy(); + case "retrywhile": + case "RetryWhile": return target.getRetryWhile(); + case "retrywhileref": + case "RetryWhileRef": return target.getRetryWhileRef(); + case "useoriginalbody": + case "UseOriginalBody": return target.isUseOriginalBody(); + case "useoriginalmessage": + case "UseOriginalMessage": return target.isUseOriginalMessage(); + default: return null; + } + } +} + diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DeadLetterChannelBuilder b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DeadLetterChannelBuilder new file mode 100644 index 0000000..358dea6 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DeadLetterChannelBuilder @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.builder.DeadLetterChannelBuilderConfigurer diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DefaultErrorHandlerBuilder b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DefaultErrorHandlerBuilder new file mode 100644 index 0000000..4365a67 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.builder.DefaultErrorHandlerBuilder @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.builder.DefaultErrorHandlerBuilderConfigurer diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java index e7c10f9..67e49b3 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java @@ -23,11 +23,13 @@ import org.apache.camel.model.errorhandler.DeadLetterChannelProperties; import org.apache.camel.model.errorhandler.DefaultErrorHandlerConfiguration; import org.apache.camel.processor.errorhandler.DeadLetterChannel; import org.apache.camel.spi.CamelLogger; +import org.apache.camel.spi.Configurer; import org.slf4j.LoggerFactory; /** * A builder of a <a href="http://camel.apache.org/dead-letter-channel.html">Dead Letter Channel</a> */ +@Configurer public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder implements DeadLetterChannelProperties { public DeadLetterChannelBuilder() { diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java index 45dcbfc..400a536 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java @@ -28,6 +28,7 @@ import org.apache.camel.model.errorhandler.DefaultErrorHandlerProperties; import org.apache.camel.processor.errorhandler.DefaultErrorHandler; import org.apache.camel.processor.errorhandler.RedeliveryPolicy; import org.apache.camel.spi.CamelLogger; +import org.apache.camel.spi.Configurer; import org.apache.camel.spi.Language; import org.apache.camel.support.ExpressionToPredicateAdapter; import org.slf4j.LoggerFactory; @@ -35,6 +36,7 @@ import org.slf4j.LoggerFactory; /** * The default error handler builder. */ +@Configurer public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport implements DefaultErrorHandlerProperties { private final DefaultErrorHandlerConfiguration configuration; diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc index 0108fee..d7e3115 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc @@ -144,6 +144,42 @@ You can also use Camel JBang to try local Kamelets, without the need to publish jbang -Dcamel.jbang.version=3.14.0 CamelJBang@apache/camel run --local-kamelet-dir=/path/to/local/kamelets earthquake.yaml ---- +=== Running Camel K integrations or bindings + +Camel also supports running Camel K integrations and binding files, which are in CRD format (Kubernetes Custom Resource Definitions). + +For example a kamelet binding file named `joke.yaml`: + +[source,yaml] +---- +apiVersion: camel.apache.org/v1alpha1 +kind: KameletBinding +metadata: + name: joke +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: chuck-norris-source + properties: + period: 2000 + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + show-headers: false +---- + +Can be run with CamelJBang: + +[source,bash] +---- +jbang -Dcamel.jbang.version=3.14.0 CamelJBang@apache/camel run joke.yaml +---- + === Search You can use the CLI to search for kamelets, components, languages and miscellaneous components (others). Running the following command will present a list of items that can be searched: diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc index fb2c28e..2567b0f 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc @@ -271,3 +271,54 @@ which demonstrate creating Camel Routes with YAML. Another way to find examples of YAML DSL is to look in https://github.com/apache/camel-kamelets[Camel Kamelets] where each Kamelet is defined using YAML. + +== Camel K support + +The `camel-yaml-dsl` is supported by Camel K. + +=== Loading Camel K integrations + +A Camel K integration (in CRD format (Custom Resource Definition in Kubernetes)) +can be loaded by `camel-yaml-dsl` and run as routes: + +[source,yaml] +---- +apiVersion: camel.apache.org/v1 +kind: Integration +metadata: + name: hello.yaml +spec: + flows: + - from: + uri: "timer:tick?period=5000" + steps: + - to: "log:tick" +---- + +=== Loading Camel K bindings + +A Camel K binding (in CRD format (Custom Resource Definition in Kubernetes)) +can be loaded by `camel-yaml-dsl` and run as routes: + +[source,yaml] +---- +apiVersion: camel.apache.org/v1alpha1 +kind: KameletBinding +metadata: + name: joke +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: chuck-norris-source + properties: + period: 2000 + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + show-headers: false +---- diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java index 2d44291..dd370a6 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java @@ -22,7 +22,9 @@ import java.util.Objects; import org.apache.camel.CamelContextAware; import org.apache.camel.api.management.ManagedResource; import org.apache.camel.builder.DeadLetterChannelBuilder; +import org.apache.camel.builder.DefaultErrorHandlerBuilder; import org.apache.camel.builder.ErrorHandlerBuilder; +import org.apache.camel.builder.NoErrorHandlerBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteConfigurationBuilder; import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport; @@ -31,10 +33,10 @@ import org.apache.camel.model.OnExceptionDefinition; import org.apache.camel.model.RouteConfigurationDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RouteTemplateDefinition; +import org.apache.camel.model.errorhandler.DefaultErrorHandlerProperties; import org.apache.camel.model.rest.RestConfigurationDefinition; import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.rest.VerbDefinition; -import org.apache.camel.processor.errorhandler.RedeliveryPolicy; import org.apache.camel.spi.CamelContextCustomizer; import org.apache.camel.spi.annotations.RoutesLoader; import org.apache.camel.support.PropertyBindingSupport; @@ -231,30 +233,47 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport { route.to(to); // is there any error handler? - // TODO: set it globally via configuration so its inherited MappingNode errorHandler = asMappingNode(nodeAt(root, "/spec/errorHandler")); if (errorHandler != null) { // there are 5 different error handlers, which one is it NodeTuple nt = errorHandler.getValue().get(0); String ehName = asText(nt.getKeyNode()); - if ("dead-letter-channel".equals(ehName)) { - DeadLetterChannelBuilder dlcb = new DeadLetterChannelBuilder(); + DefaultErrorHandlerProperties ehb = null; + if ("dead-letter-channel".equals(ehName)) { + DeadLetterChannelBuilder dlch = new DeadLetterChannelBuilder(); // endpoint MappingNode endpoint = asMappingNode(nodeAt(nt.getValueNode(), "/endpoint")); String dlq = extractCamelEndpointUri(endpoint); - dlcb.setDeadLetterUri(dlq); + dlch.setDeadLetterUri(dlq); + ehb = dlch; + } else if ("log".equals(ehName)) { + // log is the default error handler + ehb = new DefaultErrorHandlerBuilder(); + } else if ("none".equals(ehName)) { + route.errorHandler(new NoErrorHandlerBuilder()); + } else if ("bean".equals(ehName)) { + throw new IllegalArgumentException("Bean error handler is not supported"); + } else if ("ref".equals(ehName)) { + throw new IllegalArgumentException("Ref error handler is not supported"); + } - // properties + // some error handlers support additional parameters + if (ehb != null) { + // properties that are general for all kind of error handlers MappingNode prop = asMappingNode(nodeAt(nt.getValueNode(), "/parameters")); Map<String, Object> params = asMap(prop); if (params != null) { - // the parameters are for redelivery policy - RedeliveryPolicy rp = new RedeliveryPolicy(); - dlcb.setRedeliveryPolicy(rp); - PropertyBindingSupport.build().withIgnoreCase(true).bind(getCamelContext(), rp, params); + PropertyBindingSupport.build() + .withIgnoreCase(true) + .withFluentBuilder(true) + .withRemoveParameters(true) + .withCamelContext(getCamelContext()) + .withTarget(ehb) + .withProperties(params) + .bind(); } - route.errorHandler(dlcb); + route.errorHandler(ehb); } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy index 166bdc5..724f867 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy @@ -19,6 +19,8 @@ package org.apache.camel.dsl.yaml import org.apache.camel.Exchange import org.apache.camel.Processor import org.apache.camel.builder.DeadLetterChannelBuilder +import org.apache.camel.builder.DefaultErrorHandlerBuilder +import org.apache.camel.builder.NoErrorHandlerBuilder import org.apache.camel.component.mock.MockEndpoint import org.apache.camel.dsl.yaml.support.YamlTestSupport import org.apache.camel.model.ToDefinition @@ -399,4 +401,96 @@ class KameletBindingLoaderTest extends YamlTestSupport { } } + def "kamelet binding with log error handler"() { + when: + + // stub kafka for testing as it requires to setup connection to a real kafka broker + context.addComponent("kafka", context.getComponent("stub")) + + loadBindings(''' + apiVersion: camel.apache.org/v1alpha1 + kind: KameletBinding + metadata: + name: timer-event-source + spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + message: "Hello world!" + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1alpha1 + name: log-sink + errorHandler: + log: + parameters: + use-original-message: true + maximumRedeliveries: 1 + redeliveryDelay: 2000 + ''') + then: + context.routeDefinitions.size() == 3 + + with (context.routeDefinitions[0]) { + errorHandlerFactory != null + errorHandlerFactory instanceof DefaultErrorHandlerBuilder + var eh = errorHandlerFactory as DefaultErrorHandlerBuilder + eh.redeliveryPolicy.maximumRedeliveries == 1 + eh.redeliveryPolicy.redeliveryDelay == 2000 + eh.isUseOriginalMessage() == true + routeId == 'timer-event-source' + input.endpointUri == 'kamelet:timer-source?message=Hello+world%21' + outputs.size() == 1 + with (outputs[0], ToDefinition) { + endpointUri == 'kamelet:log-sink' + } + } + } + + def "kamelet binding with none error handler"() { + when: + + // stub kafka for testing as it requires to setup connection to a real kafka broker + context.addComponent("kafka", context.getComponent("stub")) + + loadBindings(''' + apiVersion: camel.apache.org/v1alpha1 + kind: KameletBinding + metadata: + name: timer-event-source + spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + message: "Hello world!" + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1alpha1 + name: log-sink + errorHandler: + none: + ''') + then: + context.routeDefinitions.size() == 3 + + with (context.routeDefinitions[0]) { + errorHandlerFactory != null + errorHandlerFactory instanceof NoErrorHandlerBuilder + routeId == 'timer-event-source' + input.endpointUri == 'kamelet:timer-source?message=Hello+world%21' + outputs.size() == 1 + with (outputs[0], ToDefinition) { + endpointUri == 'kamelet:log-sink' + } + } + } + } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletIntegrationLoaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletIntegrationLoaderTest.groovy new file mode 100644 index 0000000..289b9f4 --- /dev/null +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletIntegrationLoaderTest.groovy @@ -0,0 +1,61 @@ +/* + * 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.dsl.yaml + +import org.apache.camel.dsl.yaml.support.YamlTestSupport +import org.apache.camel.model.KameletDefinition + +class KameletIntegrationLoaderTest extends YamlTestSupport { + @Override + def doSetup() { + context.start() + } + + def "kamelet integration"() { + when: + loadIntegrations(''' + apiVersion: camel.apache.org/v1 + kind: Integration + metadata: + name: foobar + spec: + flows: + - from: + uri: 'kamelet:timer-source' + steps: + - kamelet: + name: log-sink + parameters: + showStreams: false + showHeaders: false + parameters: + message: Hello Camel K + period: 1234 + ''') + then: + context.routeDefinitions.size() == 3 + + with (context.routeDefinitions[0]) { + input.endpointUri == 'kamelet:timer-source?message=Hello Camel K&period=1234' + outputs.size() == 1 + with (outputs[0], KameletDefinition) { + name == 'log-sink?showStreams=false&showHeaders=false' + } + } + } + +} diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy index e9da693..78c81da 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy @@ -106,6 +106,16 @@ class YamlTestSupport extends Specification implements HasCamelContext { ) } + def loadIntegrations(String... resources) { + int index = 0 + + context.routesLoader.loadRoutes( + resources.collect { + it -> ResourceHelper.fromString("integration-${index++}.yaml", it.stripIndent()) + } + ) + } + def loadBindings(String... resources) { int index = 0