You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2023/06/22 18:45:50 UTC

[camel-spring-boot-examples] branch CAMEL-19308/add-minimal-aot-support created (now 7a23b3c)

This is an automated email from the ASF dual-hosted git repository.

nfilotto pushed a change to branch CAMEL-19308/add-minimal-aot-support
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot-examples.git


      at 7a23b3c  CAMEL-19308: Add a Spring Boot AOT basic example

This branch includes the following new commits:

     new 7a23b3c  CAMEL-19308: Add a Spring Boot AOT basic example

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[camel-spring-boot-examples] 01/01: CAMEL-19308: Add a Spring Boot AOT basic example

Posted by nf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nfilotto pushed a commit to branch CAMEL-19308/add-minimal-aot-support
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot-examples.git

commit 7a23b3c1c491acf643f9006b62887f77933d7f01
Author: Nicolas Filotto <nf...@talend.com>
AuthorDate: Thu Jun 22 20:45:31 2023 +0200

    CAMEL-19308: Add a Spring Boot AOT basic example
---
 README.adoc                                        |   4 +-
 aot-basic/pom.xml                                  | 150 +++++++++++++++++++++
 aot-basic/readme.adoc                              |  78 +++++++++++
 aot-basic/routes/demo-route.yaml                   |   8 ++
 aot-basic/routes/my-route.xml                      |  33 +++++
 .../src/main/java/sample/camel/Application.java    |  37 +++++
 aot-basic/src/main/java/sample/camel/MyBean.java   |  42 ++++++
 .../src/main/java/sample/camel/MyCamelRouter.java  |  45 +++++++
 .../src/main/resources/application.properties      |  34 +++++
 pom.xml                                            |   3 +-
 10 files changed, 432 insertions(+), 2 deletions(-)

diff --git a/README.adoc b/README.adoc
index 71b2ccb..d8521f8 100644
--- a/README.adoc
+++ b/README.adoc
@@ -27,12 +27,14 @@ readme's instructions.
 === Examples
 
 // examples: START
-Number of Examples: 48 (0 deprecated)
+Number of Examples: 49 (0 deprecated)
 
 [width="100%",cols="4,2,4",options="header"]
 |===
 | Example | Category | Description
 
+| link:aot-basic/readme.adoc[AOT Basic] (aot-basic) |  | An example showing how to leverage Spring Boot AOT to build a native Camel Spring Boot application
+
 | link:azure/camel-example-spring-boot-azure-eventhubs/README.adoc[Spring Boot Azure Eventhubs] (camel-example-spring-boot-azure-eventhubs) |  | An example showing how to work with Camel, Azure Event Hubs and Spring Boot
 
 | link:azure/camel-example-spring-boot-azure-servicebus/README.adoc[Spring Boot Azure Servicebus] (camel-example-spring-boot-azure-servicebus) |  | An example showing how to work with Camel, Azure Service Bus and Spring Boot
diff --git a/aot-basic/pom.xml b/aot-basic/pom.xml
new file mode 100644
index 0000000..f3150ae
--- /dev/null
+++ b/aot-basic/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel.springboot.example</groupId>
+        <artifactId>examples</artifactId>
+        <version>4.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-example-spring-boot-aot-basic</artifactId>
+    <name>Camel SB Examples :: AOT Basic</name>
+    <description>Example on how to leverage Spring Boot AOT in Camel Spring Boot</description>
+
+    <properties>
+        <category>AOT</category>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Camel BOM -->
+            <dependency>
+                <groupId>org.apache.camel.springboot</groupId>
+                <artifactId>camel-spring-boot-bom</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <!-- Camel -->
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-yaml-dsl-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-xml-io-dsl-starter</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.graalvm.buildtools</groupId>
+                <artifactId>native-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot-version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <profiles>
+        <profile>
+            <id>native</id>
+            <build>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <groupId>org.apache.maven.plugins</groupId>
+                            <artifactId>maven-jar-plugin</artifactId>
+                            <configuration>
+                                <archive>
+                                    <manifestEntries>
+                                        <Spring-Boot-Native-Processed>true</Spring-Boot-Native-Processed>
+                                    </manifestEntries>
+                                </archive>
+                            </configuration>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.springframework.boot</groupId>
+                            <artifactId>spring-boot-maven-plugin</artifactId>
+                            <configuration>
+                                <image>
+                                    <builder>paketobuildpacks/builder:tiny</builder>
+                                    <env>
+                                        <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
+                                    </env>
+                                </image>
+                            </configuration>
+                            <executions>
+                                <execution>
+                                    <id>process-aot</id>
+                                    <goals>
+                                        <goal>process-aot</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.graalvm.buildtools</groupId>
+                            <artifactId>native-maven-plugin</artifactId>
+                            <configuration>
+                                <classesDirectory>${project.build.outputDirectory}</classesDirectory>
+                                <metadataRepository>
+                                    <enabled>true</enabled>
+                                </metadataRepository>
+                                <requiredVersion>22.3</requiredVersion>
+                            </configuration>
+                            <executions>
+                                <execution>
+                                    <id>add-reachability-metadata</id>
+                                    <goals>
+                                        <goal>add-reachability-metadata</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/aot-basic/readme.adoc b/aot-basic/readme.adoc
new file mode 100644
index 0000000..4401a8e
--- /dev/null
+++ b/aot-basic/readme.adoc
@@ -0,0 +1,78 @@
+== Camel with Spring Boot AOT
+
+This example shows how you can build and execute a native image by leveraging Spring Boot AOT to launch
+Camel routes written in Java, XML and YAML in native mode.
+
+=== How to build
+
+To be able to build a GraalVM Native Image, you need to have GraalVM installed on your local machine.
+
+1. So first, download it from https://github.com/graalvm/graalvm-ce-builds/releases, choose Java 17 and the archive corresponding to your platform.
+2. Then, sets the environment variable `JAVA_HOME` to the home directory of GraalVM.
+3. Finally, install `native-image` with the command `$JAVA_HOME/bin/gu install native-image`
+
+Once, the 3 steps done properly, you can build the application with the next command:
+
+[source,console]
+----
+mvn -Pnative native:compile
+----
+
+Building a GraalVM Native Image is a relatively slow process, so be patient, it should take a couple of minutes.
+
+=== How to run
+
+A GraalVM Native Image is a complete, platform-specific executable. At this point, you don't need any Java Virtual
+Machine to launch your application.
+
+So just, launch the executable file created in the target directory as next:
+
+[source,console]
+----
+./target/camel-example-spring-boot-aot-basic
+----
+
+Your application will start in native mode. The output of the application should be of the next type:
+
+[source]
+----
+  .   ____          _            __ _ _
+ /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
+  '  |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot ::                (v3.1.0)
+
+2023-06-22T20:22:57.135+02:00  INFO 12741 --- [           main] sample.camel.Application                 : Starting AOT-processed Application using Java 17.0.7 with PID 12741 (xxx/camel-spring-boot-examples/aot-basic/target/camel-example-spring-boot-aot-basic started by yyy in xxx/camel-spring-boot-examples/aot-basic)
+2023-06-22T20:22:57.135+02:00 DEBUG 12741 --- [           main] sample.camel.Application                 : Running with Spring Boot v3.1.0, Spring v6.0.9
+2023-06-22T20:22:57.135+02:00  INFO 12741 --- [           main] sample.camel.Application                 : No active profile set, falling back to 1 default profile: "default"
+2023-06-22T20:22:57.155+02:00 DEBUG 12741 --- [           main] o.a.c.i.h.DefaultHealthCheckRegistry     : HealthCheckRepository with id registry-health-check-repository successfully registered
+2023-06-22T20:22:57.251+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0-SNAPSHOT (MyCamelNative) is starting
+2023-06-22T20:22:57.251+02:00  INFO 12741 --- [           main] c.s.b.CamelSpringBootApplicationListener : Starting CamelMainRunController to ensure the main thread keeps running
+2023-06-22T20:22:57.251+02:00  INFO 12741 --- [inRunController] org.apache.camel.main.MainSupport        : Apache Camel (Main) 4.0.0-SNAPSHOT is starting
+2023-06-22T20:22:57.265+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Routes startup (started:3)
+2023-06-22T20:22:57.266+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   :     Started helloJava (timer://java)
+2023-06-22T20:22:57.266+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   :     Started helloYAML (timer://yaml)
+2023-06-22T20:22:57.266+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   :     Started helloXML (timer://xml)
+2023-06-22T20:22:57.266+02:00  INFO 12741 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0-SNAPSHOT (MyCamelNative) started in 14ms (build:0ms init:0ms start:14ms)
+2023-06-22T20:22:57.266+02:00  INFO 12741 --- [           main] sample.camel.Application                 : Started Application in 0.144 seconds (process running for 0.159)
+2023-06-22T20:22:58.258+02:00  INFO 12741 --- [ - timer://java] helloJava                                : Hello World From Java I am invoked 1 times at Thu Jun 22 20:22:58 CEST 2023
+2023-06-22T20:22:58.269+02:00  INFO 12741 --- [ - timer://yaml] demo-route.yaml:6                        : Hello World from YAML at Thu Jun 22 20:22:58 CEST 2023
+2023-06-22T20:22:58.269+02:00  INFO 12741 --- [3 - timer://xml] my-route.xml:30                          : Hello World From XML at Thu Jun 22 20:22:58 CEST 2023
+----
+
+As you can see the application took only *159* milliseconds to fully start while the exact same application in JVM mode
+starts in more than *2* seconds.
+
+For more details, please check the related https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html[Spring Boot documentation].
+
+=== Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+https://camel.apache.org/support.html[let us know].
+
+We also love contributors, so
+https://camel.apache.org/contributing.html[get involved] :-)
+
+The Camel riders!
diff --git a/aot-basic/routes/demo-route.yaml b/aot-basic/routes/demo-route.yaml
new file mode 100644
index 0000000..b802980
--- /dev/null
+++ b/aot-basic/routes/demo-route.yaml
@@ -0,0 +1,8 @@
+- route:
+    id: helloYAML
+    from:
+      uri: timer://yaml?period=2000
+      steps:
+        - log:
+            message: "Hello World from YAML at ${header.CamelTimerFiredTime}"
+
diff --git a/aot-basic/routes/my-route.xml b/aot-basic/routes/my-route.xml
new file mode 100644
index 0000000..5515a2c
--- /dev/null
+++ b/aot-basic/routes/my-route.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/spring">
+
+    <!-- run this application with mvn spring-boot:run and then update and save this file
+         to see live changes in Camel -->
+
+    <route id="helloXML">
+        <from uri="timer:xml?period=2000"/>
+        <transform>
+            <constant>Hello World From XML</constant>
+        </transform>
+        <log message="${body} at ${header.CamelTimerFiredTime}"/>
+    </route>
+
+</routes>
\ No newline at end of file
diff --git a/aot-basic/src/main/java/sample/camel/Application.java b/aot-basic/src/main/java/sample/camel/Application.java
new file mode 100644
index 0000000..32322d9
--- /dev/null
+++ b/aot-basic/src/main/java/sample/camel/Application.java
@@ -0,0 +1,37 @@
+/*
+ * 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 sample.camel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+
+/**
+ * A sample Spring Boot application that starts the Camel routes.
+ */
+@SpringBootApplication
+public class Application {
+
+    /**
+     * A main method to start this application.
+     */
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
+//CHECKSTYLE:ON
diff --git a/aot-basic/src/main/java/sample/camel/MyBean.java b/aot-basic/src/main/java/sample/camel/MyBean.java
new file mode 100644
index 0000000..0630630
--- /dev/null
+++ b/aot-basic/src/main/java/sample/camel/MyBean.java
@@ -0,0 +1,42 @@
+/*
+ * 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 sample.camel;
+
+import org.springframework.aot.hint.annotation.Reflective;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * A bean that returns a message when you call the {@link #saySomething()} method.
+ * <p/>
+ * Uses <tt>@Component("myBean")</tt> to register this bean with the name <tt>myBean</tt>
+ * that we use in the Camel route to lookup this bean.
+ */
+@Component("myBean")
+public class MyBean {
+
+    private int counter;
+
+    @Value("${greeting} From Java")
+    private String say;
+
+    @Reflective
+    public String saySomething() {
+        return String.format("%s I am invoked %d times", say, ++counter);
+    }
+
+}
diff --git a/aot-basic/src/main/java/sample/camel/MyCamelRouter.java b/aot-basic/src/main/java/sample/camel/MyCamelRouter.java
new file mode 100644
index 0000000..aecdfc0
--- /dev/null
+++ b/aot-basic/src/main/java/sample/camel/MyCamelRouter.java
@@ -0,0 +1,45 @@
+/*
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * A simple Camel route that triggers from a timer and calls a bean and prints to system out.
+ * <p/>
+ * Use <tt>@Component</tt> to make Camel auto-detect this route when starting.
+ */
+@Component
+public class MyCamelRouter extends RouteBuilder {
+
+    // we can use spring dependency injection
+    @Autowired
+    MyBean myBean;
+
+    @Override
+    public void configure() throws Exception {
+        // start from a timer
+        from("timer:java?period={{myPeriod}}").routeId("helloJava")
+                // and call the bean
+                .bean(myBean, "saySomething")
+                // and log it
+                .log("${body} at ${header.CamelTimerFiredTime}");
+    }
+
+}
diff --git a/aot-basic/src/main/resources/application.properties b/aot-basic/src/main/resources/application.properties
new file mode 100644
index 0000000..b31e507
--- /dev/null
+++ b/aot-basic/src/main/resources/application.properties
@@ -0,0 +1,34 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+logging.level.org.springframework = INFO
+logging.level.org.apache.camel.spring.boot = INFO
+logging.level.org.apache.camel.health = DEBUG
+logging.level.org.apache.camel.impl.health = DEBUG
+logging.level.sample.camel = DEBUG
+
+camel.springboot.name = MyCamelNative
+
+camel.springboot.main-run-controller: true
+
+camel.springboot.routes-include-pattern: file:${user.dir}/routes/*.yaml,file:${user.dir}/routes/*.xml
+
+# what to say
+greeting: Hello World
+
+# how often to trigger the timer (millis)
+myPeriod: 2000
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5fadca7..6f038c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,8 +38,9 @@
 		<module>spring-boot</module>
 		<module>actuator-http-metrics</module>
 		<module>amqp</module>
+		<module>aot-basic</module>
 		<module>arangodb</module>
-                <module>artemis</module>  
+		<module>artemis</module>
 		<module>aws-secrets-manager</module>
 		<module>aws2-s3</module>
 		<module>dynamic-router-eip</module>