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 2016/06/07 12:50:32 UTC

[4/8] camel git commit: Experiment with generating spring-boot auto configuration for the Camel components.

Experiment with generating spring-boot auto configuration for the Camel components.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/2b6c992a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/2b6c992a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/2b6c992a

Branch: refs/heads/boot-generate
Commit: 2b6c992a1c8fd889c3314c024038cb8f10481be8
Parents: 0949145
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Jun 7 12:23:54 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Jun 7 12:23:54 2016 +0200

----------------------------------------------------------------------
 .../AhcComponentAutoConfiguration.java          | 31 ++++++
 components/pom.xml                              |  6 ++
 .../maven/camel-package-maven-plugin/pom.xml    | 12 ++-
 .../SpringBootAutoConfigurationMojo.java        | 99 +++++++++++++++++++-
 4 files changed, 144 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/2b6c992a/components/camel-ahc/src/main/java/org/apache/camel/component/ahc/springboot/AhcComponentAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-ahc/src/main/java/org/apache/camel/component/ahc/springboot/AhcComponentAutoConfiguration.java b/components/camel-ahc/src/main/java/org/apache/camel/component/ahc/springboot/AhcComponentAutoConfiguration.java
new file mode 100644
index 0000000..215f19c
--- /dev/null
+++ b/components/camel-ahc/src/main/java/org/apache/camel/component/ahc/springboot/AhcComponentAutoConfiguration.java
@@ -0,0 +1,31 @@
+package org.apache.camel.component.ahc.springboot;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.camel.component.ahc.AhcComponent;
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.IntrospectionSupport;
+import org.springframework.context.annotation.Bean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+
+@Configuration
+@EnableConfigurationProperties(AhcComponentConfiguration.class)
+public class AhcComponentAutoConfiguration {
+
+	@Bean
+	@ConditionalOnClass(CamelContext.class)
+	@ConditionalOnMissingBean(AhcComponent.class)
+	public AhcComponent configureComponent(CamelContext camelContext,
+			AhcComponentConfiguration configuration) throws Exception {
+		AhcComponent component = new AhcComponent();
+		component.setCamelContext(camelContext);
+		Map<String, Object> parameters = new HashMap<>();
+		IntrospectionSupport.getProperties(configuration, parameters, null);
+		IntrospectionSupport.setProperties(camelContext,
+				camelContext.getTypeConverter(), component, parameters);
+		return component;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/2b6c992a/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index 848127f..f087d41 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -39,6 +39,12 @@
       <version>${spring-boot-version}</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-autoconfigure</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>provided</scope>
+    </dependency>
  </dependencies>
 
   <modules>

http://git-wip-us.apache.org/repos/asf/camel/blob/2b6c992a/tooling/maven/camel-package-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/pom.xml b/tooling/maven/camel-package-maven-plugin/pom.xml
index 5dd6991..8acb502 100644
--- a/tooling/maven/camel-package-maven-plugin/pom.xml
+++ b/tooling/maven/camel-package-maven-plugin/pom.xml
@@ -88,7 +88,7 @@
       <artifactId>commons-io</artifactId>
     </dependency>
 
-    <!-- roaster to create java source -->
+    <!-- roaster to create java source for Spring Boot auto configuration support -->
     <dependency>
       <groupId>org.jboss.forge.roaster</groupId>
       <artifactId>roaster-api</artifactId>
@@ -99,6 +99,16 @@
       <artifactId>roaster-jdt</artifactId>
       <version>2.18.3.Final</version>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot</artifactId>
+      <version>${spring-boot-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-autoconfigure</artifactId>
+      <version>${spring-boot-version}</version>
+    </dependency>
 
     <!-- add some logging to the classpath -->
     <dependency>

http://git-wip-us.apache.org/repos/asf/camel/blob/2b6c992a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
index 1a0ff45..4770dd4 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java
@@ -20,6 +20,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -35,10 +36,18 @@ import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
 import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.source.AnnotationSource;
 import org.jboss.forge.roaster.model.source.JavaClassSource;
+import org.jboss.forge.roaster.model.source.MethodSource;
 import org.jboss.forge.roaster.model.source.PropertySource;
+import org.jboss.forge.roaster.model.util.Assert;
 import org.jboss.forge.roaster.model.util.Strings;
 import org.sonatype.plexus.build.incremental.BuildContext;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 
 import static org.apache.camel.maven.packaging.JSonSchemaHelper.getSafeValue;
 import static org.apache.camel.maven.packaging.PackageHelper.loadText;
@@ -102,14 +111,20 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
                     int pos = model.getJavaType().lastIndexOf(".");
                     String pkg = model.getJavaType().substring(0, pos) + ".springboot";
 
-                    getLog().info("Creating Java package " + pkg);
-                    createAutoConfigurationClass(pkg, model);
+                    getLog().info("Creating/Updating ComponentConfiguration source code in package " + pkg);
+                    createComponentConfigurationSource(pkg, model);
+
+                    getLog().info("Creating/Updating ComponentAutoConfiguration source code in package " + pkg);
+                    createComponentAutoConfigurationSource(pkg, model);
+
+                    getLog().info("Creating/Updating spring.factories source code");
+                    // TODO:
                 }
             }
         }
     }
 
-    private void createAutoConfigurationClass(String packageName, ComponentModel model) throws MojoFailureException {
+    private void createComponentConfigurationSource(String packageName, ComponentModel model) throws MojoFailureException {
         final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
 
         int pos = model.getJavaType().lastIndexOf(".");
@@ -160,6 +175,84 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
         }
     }
 
+    private void createComponentAutoConfigurationSource(String packageName, ComponentModel model) throws MojoFailureException {
+        final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
+
+        int pos = model.getJavaType().lastIndexOf(".");
+        String name = model.getJavaType().substring(pos + 1);
+        name = name.replace("Component", "ComponentAutoConfiguration");
+        javaClass.setPackage(packageName).setName(name);
+
+        javaClass.addAnnotation(Configuration.class);
+
+        String configurationName = name.replace("ComponentAutoConfiguration", "ComponentConfiguration");
+        AnnotationSource<JavaClassSource> ann = javaClass.addAnnotation(EnableConfigurationProperties.class);
+        ann.setLiteralValue("value", configurationName + ".class");
+
+        // add method for auto configure
+
+        javaClass.addImport("java.util.HashMap");
+        javaClass.addImport("java.util.Map");
+        javaClass.addImport(model.getJavaType());
+        javaClass.addImport("org.apache.camel.CamelContext");
+        javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
+
+        String body = createBody(model.getShortJavaType());
+
+        MethodSource<JavaClassSource> method = javaClass.addMethod()
+            .setName("configureComponent")
+            .setPublic()
+            .setBody(body)
+            .setReturnType(model.getShortJavaType())
+            .addThrows(Exception.class);
+
+        method.addParameter("CamelContext", "camelContext");
+        method.addParameter(configurationName, "configuration");
+
+        method.addAnnotation(Bean.class);
+        method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", "CamelContext.class");
+        method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", model.getShortJavaType() + ".class");
+
+        String code = javaClass.toString();
+        getLog().info("Source code generated:\n" + code);
+
+        String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
+        File target = new File(srcDir, fileName);
+
+        try {
+            if (target.exists()) {
+                String existing = FileUtils.readFileToString(target);
+                if (!code.equals(existing)) {
+                    // update
+                    FileUtils.write(target, code);
+                    getLog().info("Updated existing file: " + target);
+                } else {
+                    getLog().info("No changes to existing file: " + target);
+                }
+            } else {
+                // write
+                FileUtils.write(target, code);
+                getLog().info("Created file: " + target);
+            }
+        } catch (Exception e) {
+            throw new MojoFailureException("IOError with file " + target, e);
+        }
+    }
+
+    private String createBody(String shortJavaType) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(shortJavaType).append(" component = new ").append(shortJavaType).append("();").append("\n");
+        sb.append("component.setCamelContext(camelContext);\n");
+        sb.append("\n");
+        sb.append("Map<String, Object> parameters = new HashMap<>();\n");
+        sb.append("IntrospectionSupport.getProperties(configuration, parameters, null);\n");
+        sb.append("\n");
+        sb.append("IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), component, parameters);\n");
+        sb.append("\n");
+        sb.append("return component;");
+        return sb.toString();
+    }
+
     private String loadComponentJson(Set<File> jsonFiles, String componentName) {
         try {
             for (File file : jsonFiles) {