You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2020/09/16 13:04:45 UTC
[camel-k-runtime] branch master updated: [yaml] support for
configuring beans with the yaml dsl #376
This is an automated email from the ASF dual-hosted git repository.
lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k-runtime.git
The following commit(s) were added to refs/heads/master by this push:
new b4399bb [yaml] support for configuring beans with the yaml dsl #376
b4399bb is described below
commit b4399bbdd36652bd173b538814cf22bc29395350
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Fri Jul 10 14:30:12 2020 +0200
[yaml] support for configuring beans with the yaml dsl #376
---
.../k/loader/yaml/parser/BeansStepParser.java | 142 +++++++++++++++++++++
.../src/generated/resources/camel-yaml-dsl.json | 15 +++
.../apache/camel/k/loader/yaml/RoutesTest.groovy | 21 +++
.../test/resources/routes/RoutesTest_beans.yaml | 32 +++++
4 files changed, 210 insertions(+)
diff --git a/camel-k-loader-yaml/camel-k-loader-yaml-common/src/main/java/org/apache/camel/k/loader/yaml/parser/BeansStepParser.java b/camel-k-loader-yaml/camel-k-loader-yaml-common/src/main/java/org/apache/camel/k/loader/yaml/parser/BeansStepParser.java
new file mode 100644
index 0000000..0de129c
--- /dev/null
+++ b/camel-k-loader-yaml/camel-k-loader-yaml-common/src/main/java/org/apache/camel/k/loader/yaml/parser/BeansStepParser.java
@@ -0,0 +1,142 @@
+/*
+ * 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.loader.yaml.parser;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.type.TypeReference;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.PropertyBindingException;
+import org.apache.camel.k.annotation.yaml.YAMLNodeDefinition;
+import org.apache.camel.k.annotation.yaml.YAMLStepParser;
+import org.apache.camel.k.loader.yaml.spi.StartStepParser;
+import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.service.ServiceHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+
+
+@YAMLStepParser(id = "beans", definition = BeansStepParser.Definition.class, schema = false)
+public class BeansStepParser implements StartStepParser {
+ @Override
+ public Object process(Context context) {
+ final List<Definition> beans = context.node(new TypeReference<>() {});
+ final CamelContext camelContext = context.getCamelContext();
+
+ for (Definition bean: beans) {
+ ObjectHelper.notNull(bean.name, "bean name");
+ ObjectHelper.notNull(bean.type, "bean type");
+
+ final Map<String, Object> properties;
+
+ if (bean.properties != null) {
+ properties = new HashMap<>();
+ bean.properties.forEach((k, v) -> properties.put(StringHelper.dashToCamelCase(k), v));
+ } else {
+ properties = Collections.emptyMap();
+ }
+
+ try {
+ String type = bean.type;
+ if (!type.startsWith("#class:")) {
+ type = "#class:" + type;
+ }
+
+ Object target = PropertyBindingSupport.resolveBean(camelContext, null, type);
+
+ setPropertiesOnTarget(camelContext, target, properties);
+ camelContext.getRegistry().bind(bean.name, target);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return null;
+ }
+
+ @YAMLNodeDefinition
+ public static final class Definition {
+ @JsonProperty(required = true)
+ public String name;
+ @JsonProperty(required = true)
+ public String type;
+ @JsonProperty
+ public Map<String, Object> properties;
+ }
+
+ protected static void setPropertiesOnTarget(
+ CamelContext context,
+ Object target,
+ Map<String, Object> properties) {
+
+ ObjectHelper.notNull(context, "context");
+ ObjectHelper.notNull(target, "target");
+ ObjectHelper.notNull(properties, "properties");
+
+ PropertyConfigurer configurer = null;
+ if (target instanceof Component) {
+ // the component needs to be initialized to have the configurer ready
+ ServiceHelper.initService(target);
+ configurer = ((Component) target).getComponentPropertyConfigurer();
+ }
+
+ if (configurer == null) {
+ String name = target.getClass().getSimpleName();
+ if (target instanceof ExtendedCamelContext) {
+ // special for camel context itself as we have an extended configurer
+ name = "ExtendedCamelContext";
+ }
+
+ // see if there is a configurer for it
+ configurer = context.adapt(ExtendedCamelContext.class)
+ .getConfigurerResolver()
+ .resolvePropertyConfigurer(name, context);
+ }
+
+ try {
+ PropertyBindingSupport.build()
+ .withMandatory(true)
+ .withRemoveParameters(false)
+ .withConfigurer(configurer)
+ .withIgnoreCase(true)
+ .withFlattenProperties(true)
+ .bind(context, target, properties);
+ } catch (PropertyBindingException e) {
+ String key = e.getOptionKey();
+ if (key == null) {
+ String prefix = e.getOptionPrefix();
+ if (prefix != null && !prefix.endsWith(".")) {
+ prefix = "." + prefix;
+ }
+
+ key = prefix != null
+ ? prefix + "." + e.getPropertyName()
+ : e.getPropertyName();
+ }
+
+ // enrich the error with more precise details with option prefix and key
+ throw new PropertyBindingException(e.getTarget(), e.getPropertyName(), e.getValue(), null, key, e.getCause());
+ }
+ }
+}
diff --git a/camel-k-loader-yaml/camel-k-loader-yaml/src/generated/resources/camel-yaml-dsl.json b/camel-k-loader-yaml/camel-k-loader-yaml/src/generated/resources/camel-yaml-dsl.json
index 9bd6827..2bf79bf 100644
--- a/camel-k-loader-yaml/camel-k-loader-yaml/src/generated/resources/camel-yaml-dsl.json
+++ b/camel-k-loader-yaml/camel-k-loader-yaml/src/generated/resources/camel-yaml-dsl.json
@@ -2048,6 +2048,21 @@
}
} ]
},
+ "org.apache.camel.k.loader.yaml.parser.BeansStepParser$Definition" : {
+ "type" : "object",
+ "properties" : {
+ "name" : {
+ "type" : "string"
+ },
+ "properties" : {
+ "type" : "object"
+ },
+ "type" : {
+ "type" : "string"
+ }
+ },
+ "required" : [ "name", "type" ]
+ },
"org.apache.camel.k.loader.yaml.parser.ChoiceStepParser$Definition" : {
"type" : "object",
"properties" : {
diff --git a/camel-k-loader-yaml/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RoutesTest.groovy b/camel-k-loader-yaml/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RoutesTest.groovy
index f1cb5ae..df7b6e4 100644
--- a/camel-k-loader-yaml/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RoutesTest.groovy
+++ b/camel-k-loader-yaml/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RoutesTest.groovy
@@ -17,6 +17,7 @@
package org.apache.camel.k.loader.yaml
import org.apache.camel.component.mock.MockEndpoint
+import org.apache.camel.k.loader.yaml.support.MyBean
import org.apache.camel.k.loader.yaml.support.MyFailingProcessor
import org.apache.camel.k.loader.yaml.support.TestSupport
import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
@@ -171,4 +172,24 @@ class RoutesTest extends TestSupport {
cleanup:
context?.stop()
}
+
+ def 'beans'() {
+ when:
+ def context = startContextForSpec()
+ then:
+ with(context.registry.lookupByName('myNested'), MyBean) {
+ it.field1 == 'f1'
+ it.field2 == 'f2'
+ it.nested.field1 == 'nf1'
+ it.nested.field2 == 'nf2'
+ }
+ with(context.registry.lookupByName('myProps'), MyBean) {
+ it.field1 == 'f1_p'
+ it.field2 == 'f2_p'
+ it.nested.field1 == 'nf1_p'
+ it.nested.field2 == 'nf2_p'
+ }
+ cleanup:
+ context?.stop()
+ }
}
diff --git a/camel-k-loader-yaml/camel-k-loader-yaml/src/test/resources/routes/RoutesTest_beans.yaml b/camel-k-loader-yaml/camel-k-loader-yaml/src/test/resources/routes/RoutesTest_beans.yaml
new file mode 100644
index 0000000..e2eef2b
--- /dev/null
+++ b/camel-k-loader-yaml/camel-k-loader-yaml/src/test/resources/routes/RoutesTest_beans.yaml
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+- beans:
+ - name: myNested
+ type: org.apache.camel.k.loader.yaml.support.MyBean
+ properties:
+ field1: 'f1'
+ field2: 'f2'
+ nested:
+ field1: 'nf1'
+ field2: 'nf2'
+ - name: myProps
+ type: org.apache.camel.k.loader.yaml.support.MyBean
+ properties:
+ field1: 'f1_p'
+ field2: 'f2_p'
+ nested.field1: 'nf1_p'
+ nested.field2: 'nf2_p'
\ No newline at end of file