You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/03/13 15:52:06 UTC
[camel] 02/04: CAMEL-14670: @BeanConfigInject for injecting bean
configuration classes that are pre configured from properties files.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 640cbb707a9f4704f87c5bf6fff67dbe640d7b06
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Mar 13 15:39:39 2020 +0100
CAMEL-14670: @BeanConfigInject for injecting bean configuration classes that are pre configured from properties files.
---
.../impl/engine/CamelPostProcessorHelper.java | 63 ++++++++++++++++++++++
.../impl/engine/DefaultCamelBeanPostProcessor.java | 15 +++++-
.../test/java/org/apache/camel/impl/FooBar.java | 4 ++
.../camel/impl/{FooBar.java => FooBarConfig.java} | 21 ++++++--
.../impl/engine/CamelPostProcessorHelperTest.java | 35 ++++++++++++
5 files changed, 132 insertions(+), 6 deletions(-)
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
index da743bc..fc94c42 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
@@ -17,8 +17,12 @@
package org.apache.camel.impl.engine;
import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
import java.util.Set;
+import org.apache.camel.BeanConfigInject;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Consume;
@@ -38,8 +42,10 @@ import org.apache.camel.ProxyInstantiationException;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.Service;
import org.apache.camel.spi.BeanProxyFactory;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
import org.apache.camel.spi.PropertiesComponent;
import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.support.PropertyBindingSupport;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -302,6 +308,63 @@ public class CamelPostProcessorHelper implements CamelContextAware {
}
}
+ public Object getInjectionBeanConfigValue(Class<?> type, String name) {
+ ExtendedCamelContext ecc = (ExtendedCamelContext) getCamelContext();
+
+ // create an instance of type
+ Object bean;
+ Set<?> instances = ecc.getRegistry().findByType(type);
+ if (instances.size() == 1) {
+ bean = instances.iterator().next();
+ } else if (instances.size() > 1) {
+ return null;
+ } else {
+ // attempt to create a new instance
+ try {
+ bean = ecc.getInjector().newInstance(type);
+ } catch (Throwable e) {
+ // ignore
+ return null;
+ }
+ }
+
+ // root key
+ String rootKey = name;
+ // clip trailing dot
+ if (rootKey.endsWith(".")) {
+ rootKey = rootKey.substring(0, rootKey.length() - 1);
+ }
+
+ // get all properties and transfer to map
+ Properties props = ecc.getPropertiesComponent().loadProperties();
+ Map<String, Object> map = new LinkedHashMap<>();
+ for (String key : props.stringPropertyNames()) {
+ map.put(key, props.getProperty(key));
+ }
+
+ // lookup configurer if there is any
+ // use FQN class name first, then simple name, and root key last
+ GeneratedPropertyConfigurer configurer = null;
+ String[] names = new String[]{type.getName() + "-configurer", type.getSimpleName() + "-configurer", rootKey + "-configurer"};
+ for (String n : names) {
+ configurer = ecc.getConfigurerResolver().resolvePropertyConfigurer(n, ecc);
+ if (configurer != null) {
+ break;
+ }
+ }
+
+ new PropertyBindingSupport.Builder()
+ .withCamelContext(ecc)
+ .withIgnoreCase(true)
+ .withTarget(bean)
+ .withConfigurer(configurer)
+ .withOptionPrefix(rootKey + ".")
+ .withProperties(map)
+ .bind();
+
+ return bean;
+ }
+
/**
* Factory method to create a {@link org.apache.camel.ProducerTemplate} to
* be injected into a POJO
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index ae90f08..489fcc1 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -199,6 +199,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
injectFieldBean(field, beanInject.value(), bean, beanName);
}
+ BeanConfigInject beanConfigInject = field.getAnnotation(BeanConfigInject.class);
+ if (beanConfigInject != null) {
+ injectFieldBeanConfig(field, beanConfigInject.value(), bean, beanName);
+ }
+
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
if (endpointInject != null) {
@SuppressWarnings("deprecation")
@@ -241,6 +246,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
getPostProcessorHelper().getInjectionBeanValue(field.getType(), name));
}
+ public void injectFieldBeanConfig(Field field, String name, Object bean, String beanName) {
+ ReflectionHelper.setField(field, bean,
+ getPostProcessorHelper().getInjectionBeanConfigValue(field.getType(), name));
+ }
+
public void injectFieldProperty(Field field, String propertyName, String propertyDefaultValue, Object bean, String beanName) {
ReflectionHelper.setField(field, bean,
getPostProcessorHelper().getInjectionPropertyValue(field.getType(), propertyName, propertyDefaultValue,
@@ -465,6 +475,7 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
// we also support @BeanInject and @PropertyInject annotations
Annotation[] anns = method.getParameterAnnotations()[i];
if (anns.length == 1) {
+ // TODO: Use helper getInjectionPropertyValue
// we dont assume there are multiple annotations on the same parameter so grab first
Annotation ann = anns[0];
if (ann.annotationType() == PropertyInject.class) {
@@ -487,10 +498,10 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
// build key with default value included as this is supported during resolving
// it may be a configuration class which we want to instantiate and configure with
// project inject as base keys
- ExtendedCamelContext ecc = (ExtendedCamelContext) getOrLookupCamelContext();
- Object result = resolveBeanConfigInject(ecc, pi, type);
+ Object result = getPostProcessorHelper().getInjectionBeanConfigValue(type, pi.value());
parameters[i] = result;
} else if (ann.annotationType() == BeanInject.class) {
+ // TODO: Use helper
BeanInject bi = (BeanInject) ann;
String key = bi.value();
Object value;
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java b/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java
index 0b38d95..bb404ae 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java
@@ -23,4 +23,8 @@ public class FooBar {
public String hello(String name) {
return greeting + " " + name;
}
+
+ public void setGreeting(String greeting) {
+ this.greeting = greeting;
+ }
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java b/core/camel-core/src/test/java/org/apache/camel/impl/FooBarConfig.java
similarity index 72%
copy from core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java
copy to core/camel-core/src/test/java/org/apache/camel/impl/FooBarConfig.java
index 0b38d95..0df9b03 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/FooBar.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/FooBarConfig.java
@@ -16,11 +16,24 @@
*/
package org.apache.camel.impl;
-public class FooBar {
+public class FooBarConfig {
- private String greeting = "Hello";
+ private int age = 42;
+ private String name;
- public String hello(String name) {
- return greeting + " " + name;
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
}
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/CamelPostProcessorHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/CamelPostProcessorHelperTest.java
index 4ee2a62..fedf639 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/engine/CamelPostProcessorHelperTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/CamelPostProcessorHelperTest.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
+import org.apache.camel.BeanConfigInject;
import org.apache.camel.BeanInject;
import org.apache.camel.CamelContext;
import org.apache.camel.Consume;
@@ -40,6 +41,7 @@ import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.FooBar;
+import org.apache.camel.impl.FooBarConfig;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.support.DefaultRegistry;
@@ -464,6 +466,27 @@ public class CamelPostProcessorHelperTest extends ContextTestSupport {
}
@Test
+ public void testBeanConfigInjectByType() throws Exception {
+ Properties initial = new Properties();
+ initial.put("foobar.name", "Donald");
+ initial.put("foobar.age", "33");
+ context.getPropertiesComponent().setInitialProperties(initial);
+
+ CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
+
+ MyBeanConfigInjectByTypeBean bean = new MyBeanConfigInjectByTypeBean();
+ Field field = bean.getClass().getField("config");
+
+ BeanConfigInject beanInject = field.getAnnotation(BeanConfigInject.class);
+ Class<?> type = field.getType();
+ Object value = helper.getInjectionBeanConfigValue(type, beanInject.value());
+ field.set(bean, value);
+
+ String out = bean.doSomething("Camel");
+ assertEquals("Donald (age: 33) likes Camel", out);
+ }
+
+ @Test
public void testFluentProducerTemplateWithNoInjection() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
NoBeanInjectionTestClass myBean = new NoBeanInjectionTestClass();
@@ -742,4 +765,16 @@ public class CamelPostProcessorHelperTest extends ContextTestSupport {
}
}
+ public class MyBeanConfigInjectByTypeBean {
+
+ @BeanConfigInject("foobar")
+ public FooBarConfig config;
+
+ public String doSomething(String body) {
+ FooBar bean = new FooBar();
+ bean.setGreeting(config.getName() + " (age: " + config.getAge() + ") likes");
+ return bean.hello(body);
+ }
+ }
+
}