This is an automated email from the ASF dual-hosted git repository. ggrzybek pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit ca16f95c90b3cb2df5889ff0914c39d6de6832bc Author: Grzegorz Grzybek <[email protected]> AuthorDate: Fri May 19 11:30:37 2023 +0200 [CAMEL-18189] camel-xml-io-dsl handles <bean> element similar to YAML DSL * <camel-app> is renamed to <camel> root element (alias to <beans>) --- .../org/apache/camel/catalog/models.properties | 2 +- .../org/apache/camel/catalog/models/camel-app.json | 6 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 5 +- .../java/org/apache/camel/impl/DefaultModel.java | 74 ++-------------------- .../services/org/apache/camel/model.properties | 2 +- .../camel/model/app/{camel-app.json => camel.json} | 6 +- .../camel/model/app/ApplicationDefinition.java | 5 +- .../camel/support/PropertyBindingSupport.java | 63 ++++++++++++++++++ .../java/org/apache/camel/xml/in/ModelParser.java | 4 +- .../java/org/apache/camel/xml/out/ModelWriter.java | 2 +- .../apache/camel/dsl/jbang/core/commands/Run.java | 3 +- .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 26 +++++++- .../apache/camel/dsl/xml/io/XmlLoadAppTest.java | 55 +++++++++++++++- .../org/apache/camel/dsl/xml/io/beans/Greeter.java | 3 - .../camel/dsl/xml/io/beans/GreeterMessage.java | 8 ++- .../beans/{Greeter.java => StandaloneGreeter.java} | 9 +-- .../org/apache/camel/dsl/xml/io/camel-app1.xml | 4 +- .../org/apache/camel/dsl/xml/io/camel-app2.xml | 4 +- .../dsl/xml/io/{camel-app1.xml => camel-app3.xml} | 18 ++++-- .../dsl/xml/io/{camel-app1.xml => camel-app4.xml} | 18 ++++-- .../apache/camel/dsl/yaml/common/YamlSupport.java | 61 ------------------ .../dsl/yaml/deserializers/ModelDeserializers.java | 2 +- .../deserializers/ModelDeserializersResolver.java | 2 +- .../dsl/yaml/deserializers/BeansDeserializer.java | 2 +- .../dsl/yaml/GenerateYamlDeserializersMojo.java | 6 +- .../packaging/ModelXmlParserGeneratorMojo.java | 4 +- .../packaging/ModelXmlWriterGeneratorMojo.java | 10 +-- 27 files changed, 207 insertions(+), 197 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties index 9322ce4c9e6..ba0d5ba5d26 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties @@ -12,7 +12,7 @@ bearerToken bindy blacklistServiceFilter cachingServiceDiscovery -camel-app +camel cbor choice circuitBreaker diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/camel-app.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/camel-app.json index faea5faeddd..b160d3d1c40 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/camel-app.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/camel-app.json @@ -1,9 +1,9 @@ { "model": { "kind": "model", - "name": "camel-app", - "title": "Camel-app", - "description": "If beans reminds Spring application too much, we can use camel-app (similar to web-app from Servlet API specification).", + "name": "camel", + "title": "Camel", + "description": "If beans reminds Spring application too much, we can use camel.", "deprecated": false, "label": "configuration", "javaType": "org.apache.camel.model.app.ApplicationDefinition", diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index b7bcf95851a..a1d883d1c55 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -125,11 +125,10 @@ Deprecated: null </xs:annotation> </xs:element> - <xs:element name="camel-app" type="tns:applicationDefinition"> + <xs:element name="camel" type="tns:applicationDefinition"> <xs:annotation> <xs:documentation xml:lang="en"><![CDATA[ -If beans reminds Spring application too much, we can use camel-app (similar to -web-app from Servlet API specification). +If beans reminds Spring application too much, we can use camel. ]]></xs:documentation> </xs:annotation> </xs:element> diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java index 48a84fb41c7..81bfc255802 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java @@ -28,12 +28,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import org.apache.camel.CamelContext; -import org.apache.camel.Component; import org.apache.camel.Exchange; import org.apache.camel.Expression; import org.apache.camel.FailedToCreateRouteFromTemplateException; import org.apache.camel.NoSuchBeanException; -import org.apache.camel.PropertyBindingException; import org.apache.camel.RouteTemplateContext; import org.apache.camel.model.BeanFactoryDefinition; import org.apache.camel.model.DataFormatDefinition; @@ -66,17 +64,14 @@ import org.apache.camel.spi.ExchangeFactory; import org.apache.camel.spi.Language; import org.apache.camel.spi.ModelReifierFactory; import org.apache.camel.spi.NodeIdFactory; -import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.spi.RouteTemplateLoaderListener; import org.apache.camel.spi.RouteTemplateParameterSource; import org.apache.camel.spi.ScriptingLanguage; import org.apache.camel.support.CamelContextHelper; import org.apache.camel.support.PatternHelper; -import org.apache.camel.support.PluginHelper; import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.RouteTemplateHelper; import org.apache.camel.support.ScriptHelper; -import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.AntPathMatcher; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; @@ -581,7 +576,7 @@ public class DefaultModel implements Model { bindings.put("rtc", routeTemplateContext); Object local = slan.evaluate(script, bindings, clazz); if (!props.isEmpty()) { - setPropertiesOnTarget(camelContext, local, props); + PropertyBindingSupport.setPropertiesOnTarget(camelContext, local, props); } return local; })); @@ -598,7 +593,7 @@ public class DefaultModel implements Model { Expression exp = lan.createExpression(text); Object local = exp.evaluate(dummy, clazz); if (!props.isEmpty()) { - setPropertiesOnTarget(camelContext, local, props); + PropertyBindingSupport.setPropertiesOnTarget(camelContext, local, props); } return local; } else { @@ -654,7 +649,7 @@ public class DefaultModel implements Model { local = PropertyBindingSupport.newInstanceConstructorParameters(camelContext, clazz, params); } if (!props.isEmpty()) { - setPropertiesOnTarget(camelContext, local, props); + PropertyBindingSupport.setPropertiesOnTarget(camelContext, local, props); } return local; } catch (Exception e) { @@ -673,7 +668,7 @@ public class DefaultModel implements Model { Suppliers.memorize(() -> { Object local = camelContext.getInjector().newInstance(clazz); if (!props.isEmpty()) { - setPropertiesOnTarget(camelContext, local, props); + PropertyBindingSupport.setPropertiesOnTarget(camelContext, local, props); } return local; })); @@ -699,67 +694,6 @@ public class DefaultModel implements Model { } } - /** - * Sets the properties to the given target. - * - * @param context the context into which the properties must be set. - * @param target the object to which the properties must be set. - * @param properties the properties to set. - */ - private static void setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties) { - ObjectHelper.notNull(context, "context"); - ObjectHelper.notNull(target, "target"); - ObjectHelper.notNull(properties, "properties"); - - if (target instanceof CamelContext) { - throw new UnsupportedOperationException("Configuring the Camel Context is not supported"); - } - - 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) { - // see if there is a configurer for it - configurer = PluginHelper.getConfigurerResolver(context) - .resolvePropertyConfigurer(target.getClass().getSimpleName(), 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()); - } - } - @Override public void addRouteFromTemplatedRoute(TemplatedRouteDefinition templatedRouteDefinition) throws Exception { diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties index 129263b7cd9..8b2374be646 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties @@ -13,7 +13,7 @@ bearerToken bindy blacklistServiceFilter cachingServiceDiscovery -camel-app +camel cbor choice circuitBreaker diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel-app.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel.json similarity index 94% rename from core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel-app.json rename to core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel.json index faea5faeddd..b160d3d1c40 100644 --- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel-app.json +++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/camel.json @@ -1,9 +1,9 @@ { "model": { "kind": "model", - "name": "camel-app", - "title": "Camel-app", - "description": "If beans reminds Spring application too much, we can use camel-app (similar to web-app from Servlet API specification).", + "name": "camel", + "title": "Camel", + "description": "If beans reminds Spring application too much, we can use camel.", "deprecated": false, "label": "configuration", "javaType": "org.apache.camel.model.app.ApplicationDefinition", diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/app/ApplicationDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/app/ApplicationDefinition.java index e416c7cc3cc..4b065387893 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/app/ApplicationDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/app/ApplicationDefinition.java @@ -21,10 +21,9 @@ import jakarta.xml.bind.annotation.XmlRootElement; import org.apache.camel.spi.Metadata; /** - * If "beans" reminds Spring application too much, we can use "camel-app" (similar to "web-app" from Servlet API - * specification). + * If "beans" reminds Spring application too much, we can use "camel". */ @Metadata(label = "configuration") -@XmlRootElement(name = "camel-app") +@XmlRootElement(name = "camel") public class ApplicationDefinition extends BeansDefinition { } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java index 17c9be43558..6409e48aeb4 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java @@ -36,11 +36,13 @@ import java.util.TreeMap; import java.util.stream.Collectors; import org.apache.camel.CamelContext; +import org.apache.camel.Component; import org.apache.camel.PropertyBindingException; import org.apache.camel.spi.BeanIntrospection; import org.apache.camel.spi.PropertiesComponent; import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.StringQuoteHelper; @@ -151,6 +153,67 @@ public final class PropertyBindingSupport { return PropertyBindingSupport.build().withFlattenProperties(true).bind(camelContext, target, properties); } + /** + * Sets the properties to the given target. + * + * @param context the context into which the properties must be set. + * @param target the object to which the properties must be set. + * @param properties the properties to set. + */ + public static void setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties) { + org.apache.camel.util.ObjectHelper.notNull(context, "context"); + org.apache.camel.util.ObjectHelper.notNull(target, "target"); + org.apache.camel.util.ObjectHelper.notNull(properties, "properties"); + + if (target instanceof CamelContext) { + throw new UnsupportedOperationException("Configuring the Camel Context is not supported"); + } + + 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) { + // see if there is a configurer for it + configurer = PluginHelper.getConfigurerResolver(context) + .resolvePropertyConfigurer(target.getClass().getSimpleName(), 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()); + } + } + /** * Binds the properties with the given prefix to the target object, and removes the property that was bound from * properties. Note that the prefix is removed from the key before the property is bound. diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index 4275582c8b3..703cea305c2 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -1560,7 +1560,7 @@ public class ModelParser extends BaseParser { } public Optional<ApplicationDefinition> parseApplicationDefinition() throws IOException, XmlPullParserException { - String tag = getNextTag("beans", "camel-app"); + String tag = getNextTag("beans", "camel"); if (tag != null) { return Optional.of(doParseApplicationDefinition()); } @@ -1572,7 +1572,7 @@ public class ModelParser extends BaseParser { } public Optional<BeansDefinition> parseBeansDefinition() throws IOException, XmlPullParserException { - String tag = getNextTag("beans", "camel-app"); + String tag = getNextTag("beans", "camel"); if (tag != null) { return Optional.of(doParseBeansDefinition()); } diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 66abe00a04d..cd21cf09aa8 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -486,7 +486,7 @@ public class ModelWriter extends BaseWriter { public void writeApplicationDefinition( ApplicationDefinition def) throws IOException { - doWriteApplicationDefinition("camel-app", def); + doWriteApplicationDefinition("camel", def); } public void writeBeansDefinition(BeansDefinition def) throws IOException { doWriteBeansDefinition("beans", def); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java index 2b59afbf1e1..1e6a564e57f 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java @@ -91,7 +91,8 @@ public class Run extends CamelCommand { "routeTemplate", "routeTemplates", "templatedRoute", "templatedRoutes", "rest", "rests", - "routeConfiguration", "beans" + "routeConfiguration", + "beans", "camel" }; private static final Set<String> ACCEPTED_XML_ROOT_ELEMENTS diff --git a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java index fb4387dffe1..1709a018e1d 100644 --- a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java +++ b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java @@ -35,6 +35,7 @@ import org.apache.camel.model.RoutesDefinition; import org.apache.camel.model.TemplatedRouteDefinition; import org.apache.camel.model.TemplatedRoutesDefinition; import org.apache.camel.model.app.BeansDefinition; +import org.apache.camel.model.app.RegistryBeanDefinition; import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.rest.RestsDefinition; import org.apache.camel.spi.Injector; @@ -43,6 +44,7 @@ import org.apache.camel.spi.Registry; import org.apache.camel.spi.Resource; import org.apache.camel.spi.annotations.RoutesLoader; import org.apache.camel.support.CachedResource; +import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.xml.in.ModelParser; import org.apache.camel.xml.io.util.XmlStreamDetector; import org.apache.camel.xml.io.util.XmlStreamInfo; @@ -85,7 +87,7 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { @Override public void configure() throws Exception { switch (xmlInfo.getRootElementName()) { - case "beans", "camel-app" -> + case "beans", "camel" -> new ModelParser(resource, xmlInfo.getRootElementNamespace()) .parseBeansDefinition() .ifPresent(this::allInOne); @@ -150,6 +152,28 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { } } + for (RegistryBeanDefinition bean : app.getBeans()) { + String type = bean.getType(); + String name = bean.getName(); + if (name == null || "".equals(name.trim())) { + name = type; + } + if (type != null && !type.startsWith("#")) { + type = "#class:" + type; + try { + final Object target = PropertyBindingSupport.resolveBean(getCamelContext(), type); + + if (bean.getProperties() != null && !bean.getProperties().isEmpty()) { + PropertyBindingSupport.setPropertiesOnTarget(getCamelContext(), target, bean.getProperties()); + } + getCamelContext().getRegistry().unbind(name); + getCamelContext().getRegistry().bind(name, target); + } catch (Exception e) { + LOG.warn("Problem creating bean {}", type, e); + } + } + } + app.getRests().forEach(r -> { List<RestDefinition> list = new ArrayList<>(); list.add(r); diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java index 8034a36f4b0..ddfe78459ea 100644 --- a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java @@ -17,6 +17,7 @@ package org.apache.camel.dsl.xml.io; import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.dsl.xml.io.beans.GreeterMessage; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.spi.Resource; import org.apache.camel.support.PluginHelper; @@ -32,7 +33,8 @@ public class XmlLoadAppTest { try (DefaultCamelContext context = new DefaultCamelContext()) { context.start(); - // load route from XML and add them to the existing camel context + // load route from XML and add them both to the existing camel context + // only first XML declares component scanning (to put beans into the registry) String[] contexts = new String[] { "camel-app1.xml", "camel-app2.xml" @@ -48,6 +50,10 @@ public class XmlLoadAppTest { assertNotNull(context.getRoute("r2"), "Loaded r2 route should be there"); assertEquals(2, context.getRoutes().size()); + // tweak bean in registry + GreeterMessage gm = context.getRegistry().findSingleByType(GreeterMessage.class); + gm.setMsg("Hello"); + // test that loaded route works MockEndpoint y1 = context.getEndpoint("mock:y1", MockEndpoint.class); y1.expectedBodiesReceived("Hello World"); @@ -61,4 +67,51 @@ public class XmlLoadAppTest { } } + @Test + public void testLoadCamelAppWithBeansAndDI() throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + context.start(); + + // camel-app3 registers two beans and 2nd one uses @BeanInject on first one + + Resource resource = PluginHelper.getResourceLoader(context).resolveResource( + "/org/apache/camel/dsl/xml/io/camel-app3.xml"); + + PluginHelper.getRoutesLoader(context).loadRoutes(resource); + + assertNotNull(context.getRoute("r3"), "Loaded r3 route should be there"); + assertEquals(1, context.getRoutes().size()); + + // test that loaded route works + MockEndpoint y3 = context.getEndpoint("mock:y3", MockEndpoint.class); + y3.expectedBodiesReceived("Hello World"); + context.createProducerTemplate().sendBody("direct:x3", "I'm World"); + y3.assertIsSatisfied(); + } + } + + @Test + public void testLoadCamelAppWithBeansAndFlattenedProperties() throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + context.start(); + + // camel-app4 registers one bean, where its dependency is created from the flattened properties + // and using org.apache.camel.spi.Injector.newInstance() + + Resource resource = PluginHelper.getResourceLoader(context).resolveResource( + "/org/apache/camel/dsl/xml/io/camel-app4.xml"); + + PluginHelper.getRoutesLoader(context).loadRoutes(resource); + + assertNotNull(context.getRoute("r4"), "Loaded r4 route should be there"); + assertEquals(1, context.getRoutes().size()); + + // test that loaded route works + MockEndpoint y4 = context.getEndpoint("mock:y4", MockEndpoint.class); + y4.expectedBodiesReceived("Hello World"); + context.createProducerTemplate().sendBody("direct:x4", "I'm World"); + y4.assertIsSatisfied(); + } + } + } diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java index 6bef9a02efa..0cfcd38045e 100644 --- a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java @@ -27,9 +27,6 @@ public class Greeter implements Processor { private GreeterMessage message; - public Greeter() { - } - @BeanInject public void setMessage(GreeterMessage message) { this.message = message; diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/GreeterMessage.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/GreeterMessage.java index f7344b34913..368f24a9c38 100644 --- a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/GreeterMessage.java +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/GreeterMessage.java @@ -21,8 +21,14 @@ import org.apache.camel.BindToRegistry; @BindToRegistry public class GreeterMessage { + private String msg; + public String getMsg() { - return "Hello"; + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; } } diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/StandaloneGreeter.java similarity index 86% copy from dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java copy to dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/StandaloneGreeter.java index 6bef9a02efa..92cdba2496e 100644 --- a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/Greeter.java +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/StandaloneGreeter.java @@ -16,21 +16,14 @@ */ package org.apache.camel.dsl.xml.io.beans; -import org.apache.camel.BeanInject; -import org.apache.camel.BindToRegistry; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.util.StringHelper; -@BindToRegistry("bean-from-registry") -public class Greeter implements Processor { +public class StandaloneGreeter implements Processor { private GreeterMessage message; - public Greeter() { - } - - @BeanInject public void setMessage(GreeterMessage message) { this.message = message; } diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml index e163f0cd11a..787a3f9ff8d 100644 --- a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml @@ -17,7 +17,7 @@ limitations under the License. --> -<camel-app xmlns="http://camel.apache.org/schema/spring"> +<camel xmlns="http://camel.apache.org/schema/spring"> <component-scan base-package="org.apache.camel.dsl.xml.io.beans" /> @@ -27,4 +27,4 @@ <to uri="mock:y1"/> </route> -</camel-app> +</camel> diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app2.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app2.xml index 968495ac991..c6eb123ca5a 100644 --- a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app2.xml +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app2.xml @@ -17,7 +17,7 @@ limitations under the License. --> -<camel-app xmlns:s="http://www.springframework.org/schema/beans"> +<camel xmlns:s="http://www.springframework.org/schema/beans"> <route id="r2"> <from uri="direct:x2"/> @@ -25,4 +25,4 @@ <to uri="mock:y2"/> </route> -</camel-app> +</camel> diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app3.xml similarity index 66% copy from dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml copy to dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app3.xml index e163f0cd11a..621bcf1d207 100644 --- a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app3.xml @@ -17,14 +17,20 @@ limitations under the License. --> -<camel-app xmlns="http://camel.apache.org/schema/spring"> +<camel xmlns="http://camel.apache.org/schema/spring" xmlns:s="http://www.springframework.org/schema/beans"> - <component-scan base-package="org.apache.camel.dsl.xml.io.beans" /> + <bean type="org.apache.camel.dsl.xml.io.beans.GreeterMessage"> + <properties> + <property key="msg" value="Hello" /> + </properties> + </bean> - <route id="r1"> - <from uri="direct:x1"/> + <bean name="bean-from-registry" type="org.apache.camel.dsl.xml.io.beans.Greeter" /> + + <route id="r3"> + <from uri="direct:x3"/> <bean ref="bean-from-registry" /> - <to uri="mock:y1"/> + <to uri="mock:y3"/> </route> -</camel-app> +</camel> diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app4.xml similarity index 65% copy from dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml copy to dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app4.xml index e163f0cd11a..646e7dba0dd 100644 --- a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app1.xml +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app4.xml @@ -17,14 +17,18 @@ limitations under the License. --> -<camel-app xmlns="http://camel.apache.org/schema/spring"> +<camel xmlns="http://camel.apache.org/schema/spring" xmlns:s="http://www.springframework.org/schema/beans"> - <component-scan base-package="org.apache.camel.dsl.xml.io.beans" /> + <bean name="xml-bean-from-registry" type="org.apache.camel.dsl.xml.io.beans.StandaloneGreeter"> + <properties> + <property key="message.msg" value="Hello" /> + </properties> + </bean> - <route id="r1"> - <from uri="direct:x1"/> - <bean ref="bean-from-registry" /> - <to uri="mock:y1"/> + <route id="r4"> + <from uri="direct:x4"/> + <bean ref="xml-bean-from-registry" /> + <to uri="mock:y4"/> </route> -</camel-app> +</camel> diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java index 874eb41909c..1c2b53f465f 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java @@ -24,8 +24,6 @@ import java.util.TreeMap; import java.util.function.Function; import org.apache.camel.CamelContext; -import org.apache.camel.Component; -import org.apache.camel.PropertyBindingException; import org.apache.camel.dsl.yaml.common.exception.InvalidEndpointException; import org.apache.camel.dsl.yaml.common.exception.InvalidNodeTypeException; import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException; @@ -33,11 +31,6 @@ import org.apache.camel.dsl.yaml.common.exception.UnsupportedNodeTypeException; import org.apache.camel.model.RouteDefinition; import org.apache.camel.spi.CamelContextCustomizer; import org.apache.camel.spi.EndpointUriFactory; -import org.apache.camel.spi.PropertyConfigurer; -import org.apache.camel.support.PluginHelper; -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; import org.apache.camel.util.URISupport; import org.snakeyaml.engine.v2.api.ConstructNode; @@ -58,60 +51,6 @@ public final class YamlSupport { private YamlSupport() { } - public static void setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties) { - ObjectHelper.notNull(context, "context"); - ObjectHelper.notNull(target, "target"); - ObjectHelper.notNull(properties, "properties"); - - if (target instanceof CamelContext) { - throw new UnsupportedOperationException("Configuring the Camel Context is not supported"); - } - - 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) { - // see if there is a configurer for it - configurer = PluginHelper.getConfigurerResolver(context) - .resolvePropertyConfigurer(target.getClass().getSimpleName(), 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()); - } - } - public static CamelContextCustomizer customizer(Collection<CamelContextCustomizer> customizers) { return new CamelContextCustomizer() { @Override diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 229062f100c..c21941957bd 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -589,7 +589,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { } @YamlType( - nodes = "camel-app", + nodes = "camel", types = org.apache.camel.model.app.ApplicationDefinition.class, order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1, properties = { diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java index 0b0785c531d..0165a5f5ffe 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java @@ -22,7 +22,7 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve case "api-key": return new ModelDeserializers.ApiKeyDefinitionDeserializer(); case "apiKey": return new ModelDeserializers.ApiKeyDefinitionDeserializer(); case "org.apache.camel.model.rest.ApiKeyDefinition": return new ModelDeserializers.ApiKeyDefinitionDeserializer(); - case "camel-app": return new ModelDeserializers.ApplicationDefinitionDeserializer(); + case "camel": return new ModelDeserializers.ApplicationDefinitionDeserializer(); case "org.apache.camel.model.app.ApplicationDefinition": return new ModelDeserializers.ApplicationDefinitionDeserializer(); case "avro": return new ModelDeserializers.AvroDataFormatDeserializer(); case "org.apache.camel.model.dataformat.AvroDataFormat": return new ModelDeserializers.AvroDataFormatDeserializer(); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java index ea6ab6fdc6f..e4bb570b140 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java @@ -85,7 +85,7 @@ public class BeansDeserializer extends YamlDeserializerSupport implements Constr final Object target = PropertyBindingSupport.resolveBean(context, bean.getType()); if (bean.getProperties() != null && !bean.getProperties().isEmpty()) { - YamlSupport.setPropertiesOnTarget(context, target, bean.getProperties()); + PropertyBindingSupport.setPropertiesOnTarget(context, target, bean.getProperties()); } return target; diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java index 54fab99f323..6aebfb59411 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java @@ -858,10 +858,8 @@ public class GenerateYamlDeserializersMojo extends GenerateYamlSupportMojo { if (adapterClassInfo.superClassType().kind() == Type.Kind.PARAMETERIZED_TYPE) { List<Type> arguments = adapterClassInfo.superClassType().asParameterizedType().arguments(); if (arguments.size() == 2) { - // extends XmlAdapter<BeanPropertiesDefinition, Map<String, Object>> -// Type type = arguments.get(0); -// cb.addStatement("$L val = new $L().unmarshal(asType(node, $L.class))", -// field.type().name().toString(), adapterClass, type.name()); + // this is for extends XmlAdapter<BeanPropertiesDefinition, Map<String, Object>> + // we can't use JaxbUnmarshaller here (as in XML DSL) and we have to convert to map directly Type type = arguments.get(1); if (type.name().toString().equals("java.util.Map")) { cb.addStatement("$L val = asMap(node)", field.type().name().toString()); diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java index ebf277f8a3c..9fb32117d77 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java @@ -536,14 +536,14 @@ public class ModelXmlParserGeneratorMojo extends AbstractGeneratorMojo { }); if (clazz == beansDefinitionClass || clazz == applicationDefinitionClass) { - // for beans/camel-app we want public methods to be invoked by camel-xml-io-dsl + // for beans/camel we want public methods to be invoked by camel-xml-io-dsl parser.addMethod().setPublic() .setReturnType(new GenericType(Optional.class, new GenericType(clazz))) .setName("parse" + name) .addThrows(IOException.class) .addThrows(XML_PULL_PARSER_EXCEPTION) - .setBody(String.format("String tag = getNextTag(\"%s\", \"%s\");", "beans", "camel-app"), + .setBody(String.format("String tag = getNextTag(\"%s\", \"%s\");", "beans", "camel"), "if (tag != null) {", String.format(" return Optional.of(doParse%s());", name), "}", diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java index 3e510dc9d8b..4fa3a337388 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java @@ -800,7 +800,7 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo { } else if (accessType == XmlAccessType.FIELD) { return m -> m.getDeclaringClass() == clazz && ((isSetter(m) || isGetter(m)) && isXmlBindAnnotated(m) - || isField(m) && /*isNotAnyXml(m) && */!Modifier.isStatic(m.getModifiers()) && !Modifier.isTransient(m.getModifiers())); + || isField(m) && !Modifier.isStatic(m.getModifiers()) && !Modifier.isTransient(m.getModifiers())); } else if (accessType == XmlAccessType.PUBLIC_MEMBER) { return m -> m.getDeclaringClass() == clazz && (Modifier.isPublic(m.getModifiers()) || isXmlBindAnnotated(m)); @@ -812,13 +812,7 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo { private boolean isXmlBindAnnotated(Member m) { return Stream.of(((AnnotatedElement) m).getAnnotations()) - .anyMatch(a -> a.getClass().getAnnotatedInterfaces()[0].getType().getTypeName().startsWith("jakarta.xml.bind.annotation.") - /*&& !a.getClass().getAnnotatedInterfaces()[0].getType().getTypeName().endsWith("XmlAnyElement")*/); - } - - private boolean isNotAnyXml(Member m) { - return Stream.of(((AnnotatedElement) m).getAnnotations()) - .noneMatch(a -> a.getClass().getAnnotatedInterfaces()[0].getType().getTypeName().equals("jakarta.xml.bind.annotation.XmlAnyElement")); + .anyMatch(a -> a.getClass().getAnnotatedInterfaces()[0].getType().getTypeName().startsWith("jakarta.xml.bind.annotation.")); } private boolean isField(Member member) {
