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 2019/06/17 12:04:39 UTC
[camel] 04/20: CAMEL-13647: Allow to do autowrire by classpath.
Quick and dirty prototype.
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 5ced786ad0b307cf032f6a50d0780c399da6f477
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Jun 16 08:13:22 2019 +0200
CAMEL-13647: Allow to do autowrire by classpath. Quick and dirty prototype.
---
.../java/org/apache/camel/maven/AutowireMojo.java | 75 ++++++++++++++++++----
.../src/main/resources/known-types.properties | 22 +++++++
.../camel/support/PropertyBindingSupport.java | 1 +
.../org/apache/camel/example/MyRouteBuilder.java | 2 +
.../src/main/resources/application.properties | 3 +
5 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
index 02616f7..ab205f3 100644
--- a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
+++ b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
@@ -18,6 +18,7 @@ package org.apache.camel.maven;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
@@ -103,6 +104,10 @@ public class AutowireMojo extends AbstractExecMojo {
private transient ClassLoader classLoader;
+ // TODO: Allow to configure known types in xml config, or refer to external file
+ // TODO: Allow to configure include/exclude names on components,names
+ // TODO: Skip some known types
+
// CHECKSTYLE:OFF
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
@@ -159,7 +164,13 @@ public class AutowireMojo extends AbstractExecMojo {
.addClassLoader(classLoader)
.setScanners(new SubTypesScanner()));
- List<String> autowires = findAutowireComponentOptionsByClasspath(catalog, components, reflections);
+ // load known types
+ Properties knownTypes = loadKnownTypes();
+ getLog().debug("Loaded known-types: " + knownTypes);
+
+ // find the autowire via classpath scanning
+ List<String> autowires = findAutowireComponentOptionsByClasspath(catalog, components, reflections, knownTypes);
+
if (!autowires.isEmpty()) {
outFolder.mkdirs();
File file = new File(outFolder, "autowire.properties");
@@ -178,7 +189,21 @@ public class AutowireMojo extends AbstractExecMojo {
}
}
- protected List<String> findAutowireComponentOptionsByClasspath(CamelCatalog catalog, Set<String> components, Reflections reflections) {
+ protected Properties loadKnownTypes() throws MojoFailureException {
+ Properties knownTypes = new Properties();
+ try {
+ InputStream is = AutowireMojo.class.getResourceAsStream("/known-types.properties");
+ if (is != null) {
+ knownTypes.load(is);
+ }
+ } catch (IOException e) {
+ throw new MojoFailureException("Cannot load known-types.properties from classpath");
+ }
+ return knownTypes;
+ }
+
+ protected List<String> findAutowireComponentOptionsByClasspath(CamelCatalog catalog, Set<String> components,
+ Reflections reflections, Properties knownTypes) {
List<String> autowires = new ArrayList<>();
for (String componentName : components) {
@@ -199,25 +224,21 @@ public class AutowireMojo extends AbstractExecMojo {
if ("object".equals(type)) {
try {
Class clazz = classLoader.loadClass(javaType);
- if (clazz.isInterface()) {
+ if (clazz.isInterface() && isComplexUserType(clazz)) {
Set<Class<?>> classes = reflections.getSubTypesOf(clazz);
// filter classes to not be interfaces or not a top level class
classes = classes.stream().filter(c -> !c.isInterface() && c.getEnclosingClass() == null).collect(Collectors.toSet());
- if (classes.size() == 1) {
- Class cls = classes.iterator().next();
- if (isValidAutowireClass(cls)) {
- String line = "camel.component." + componentName + "." + name + "=#class:" + cls.getName();
- getLog().debug(line);
- autowires.add(line);
- }
- } else if (classes.size() > 1) {
- getLog().debug("Found " + classes.size() + " for autowire: " + componentName + "." + name + ". Cannot chose one class: " + classes);
+ Class best = chooseBestKnownType(clazz, classes, knownTypes);
+ if (isValidAutowireClass(best)) {
+ String line = "camel.component." + componentName + "." + name + "=#class:" + best.getName();
+ getLog().debug(line);
+ autowires.add(line);
}
}
} catch (Exception e) {
- getLog().debug("Cannot load class: " + name, e);
// ignore
+ getLog().debug("Cannot load class: " + name, e);
}
}
}
@@ -226,6 +247,34 @@ public class AutowireMojo extends AbstractExecMojo {
return autowires;
}
+ protected Class chooseBestKnownType(Class type, Set<Class<?>> candidates, Properties knownTypes) {
+ String known = knownTypes.getProperty(type.getName());
+ if (known != null) {
+ for (String k : known.split(",")) {
+ // special as we should skip this option
+ if ("#skip#".equals(k)) {
+ return null;
+ }
+ Class found = candidates.stream().filter(c -> c.getName().equals(k)).findFirst().orElse(null);
+ if (found != null) {
+ return found;
+ }
+ }
+ }
+
+ if (candidates.size() == 1) {
+ return candidates.iterator().next();
+ } else if (candidates.size() > 1) {
+ getLog().debug("Cannot chose best type: " + type.getName() + " among " + candidates.size() + " implementations: " + candidates);
+ }
+ return null;
+ }
+
+ private static boolean isComplexUserType(Class type) {
+ // lets consider all non java, as complex types
+ return type != null && !type.isPrimitive() && !type.getName().startsWith("java.");
+ }
+
protected boolean isValidAutowireClass(Class clazz) {
// skip all from Apache Camel and regular JDK as they would be default anyway
return !clazz.getName().startsWith("org.apache.camel");
diff --git a/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties b/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties
new file mode 100644
index 0000000..78971fe
--- /dev/null
+++ b/catalog/camel-main-maven-plugin/src/main/resources/known-types.properties
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# favour these classes if there are multiple on the classpath
+javax.jms.ConnectionFactory=org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory
+
+# skip these types
+org.springframework.jms.core.JmsOperations=#skip#
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 7298242..10306f0 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
@@ -279,6 +279,7 @@ public final class PropertyBindingSupport {
* @param target the target object
* @return true if one ore more properties was auto wired
*/
+ @Deprecated
public static boolean autowireInterfacePropertiesFromClasspath(CamelContext camelContext, Object target) {
return autowireInterfacePropertiesFromClasspath(camelContext, target, false, false, null);
}
diff --git a/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java b/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
index d98ae5f..09546c0 100644
--- a/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
+++ b/examples/camel-example-main/src/main/java/org/apache/camel/example/MyRouteBuilder.java
@@ -27,5 +27,7 @@ public class MyRouteBuilder extends RouteBuilder {
.log("${body}")
.bean("myBean", "bye")
.log("${body}");
+
+ from("jms:queue:cheese").to("log:cheese");
}
}
diff --git a/examples/camel-example-main/src/main/resources/application.properties b/examples/camel-example-main/src/main/resources/application.properties
index 71ab7ab..334af88 100644
--- a/examples/camel-example-main/src/main/resources/application.properties
+++ b/examples/camel-example-main/src/main/resources/application.properties
@@ -42,6 +42,9 @@ camel.component.quartz2.start-delayed-seconds = 3
# you can configure whether OS environment should override (=2 which is default) or as fallback (=1)
### camel.component.properties.environment-variable-mode=1
+camel.component.jms.configuration.connectionFactory=#class:org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory
+camel.component.jms.configuration.connectionFactory.brokerUrl=localhost:61616
+
# properties used in the route
myCron = 0/2 * * * * ?