You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2019/08/28 10:05:56 UTC

[camel-quarkus] branch master updated: Groovy script to scaffold an integration test when creating a new extension

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

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/master by this push:
     new 324e537  Groovy script to scaffold an integration test when creating a new extension
     new 121e6c1  Merge pull request #160 from ppalaga/190823-itest-stub-generator
324e537 is described below

commit 324e5372e801b4834299aebb077de07a3cd60e9b
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Fri Aug 23 12:24:45 2019 +0200

    Groovy script to scaffold an integration test when creating a new
    extension
---
 build/create-extension-templates/IT.java           |   8 ++
 build/create-extension-templates/Test.java         |  27 +++++
 build/create-extension-templates/TestResource.java |  69 +++++++++++
 .../TestRouteBuilder.java                          |  27 +++++
 .../integration-test-pom.xml                       | 114 ++++++++++++++++++
 build/scripts/scaffold-integration-test.groovy     | 131 +++++++++++++++++++++
 docs/modules/ROOT/pages/contributor-guide.adoc     |  21 ++--
 extensions/pom.xml                                 |  41 ++++++-
 8 files changed, 430 insertions(+), 8 deletions(-)

diff --git a/build/create-extension-templates/IT.java b/build/create-extension-templates/IT.java
new file mode 100644
index 0000000..dc31bd0
--- /dev/null
+++ b/build/create-extension-templates/IT.java
@@ -0,0 +1,8 @@
+package [=javaPackageBase].it;
+
+import io.quarkus.test.junit.SubstrateTest;
+
+@SubstrateTest
+class [=artifactIdBaseCamelCase]IT extends [=artifactIdBaseCamelCase]Test {
+
+}
diff --git a/build/create-extension-templates/Test.java b/build/create-extension-templates/Test.java
new file mode 100644
index 0000000..d133ddc
--- /dev/null
+++ b/build/create-extension-templates/Test.java
@@ -0,0 +1,27 @@
+package [=javaPackageBase].it;
+
+import java.util.UUID;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+
+@QuarkusTest
+class [=artifactIdBaseCamelCase]Test {
+
+    @Test
+    public void test() {
+        final String msg = UUID.randomUUID().toString().replace("-", "");
+        RestAssured.given() //
+            .contentType(ContentType.TEXT).body(msg).post("/[=artifactIdBase]/post") //
+            .then().statusCode(201);
+
+        Assertions.fail("Add some assertions to " + getClass().getName());
+
+        RestAssured.get("/[=artifactIdBase]/get").then().statusCode(200);
+    }
+
+}
diff --git a/build/create-extension-templates/TestResource.java b/build/create-extension-templates/TestResource.java
new file mode 100644
index 0000000..a9c067b
--- /dev/null
+++ b/build/create-extension-templates/TestResource.java
@@ -0,0 +1,69 @@
+/*
+ * 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 [=javaPackageBase].it;
+
+import java.net.URI;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.ProducerTemplate;
+import org.jboss.logging.Logger;
+
+@Path("/[=artifactIdBase]")
+@ApplicationScoped
+public class [=artifactIdBaseCamelCase]Resource {
+
+    private static final Logger log = Logger.getLogger([=artifactIdBaseCamelCase]Resource.class);
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Inject
+    ConsumerTemplate consumerTemplate;
+
+    @Path("/get")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String get() throws Exception {
+        final String message = consumerTemplate.receiveBodyNoWait("[=artifactIdBase]:--fix-me--", String.class);
+        log.infof("Received from [=artifactIdBase]: %s", message);
+        return message;
+    }
+
+    @Path("/post")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response post(String message) throws Exception {
+        log.infof("Sending to [=artifactIdBase]: %s", message);
+        final String response = producerTemplate.requestBody("[=artifactIdBase]:--fix-me--", message, String.class);
+        log.infof("Got response from [=artifactIdBase]: %s", response);
+        return Response
+                .created(new URI("https://camel.apache.org/"))
+                .entity(response)
+                .build();
+    }
+}
diff --git a/build/create-extension-templates/TestRouteBuilder.java b/build/create-extension-templates/TestRouteBuilder.java
new file mode 100644
index 0000000..6a36505
--- /dev/null
+++ b/build/create-extension-templates/TestRouteBuilder.java
@@ -0,0 +1,27 @@
+/*
+ * 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 [=javaPackageBase].it;
+
+import org.apache.camel.builder.RouteBuilder;
+
+
+public class [=artifactIdBaseCamelCase]RouteBuilder extends RouteBuilder {
+    @Override
+    public void configure() {
+        // Add some routes or remove this class
+    }
+}
diff --git a/build/create-extension-templates/integration-test-pom.xml b/build/create-extension-templates/integration-test-pom.xml
new file mode 100644
index 0000000..c8cefb9
--- /dev/null
+++ b/build/create-extension-templates/integration-test-pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-integration-tests</artifactId>
+        <version>0.1.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-quarkus-integration-test-[=artifactIdBase]</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: [=nameBase]</name>
+    <description>Integration tests for Camel Quarkus [=nameBase] extension</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-[=artifactIdBase]</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-log</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.rest-assured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.quarkus</groupId>
+                <artifactId>quarkus-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>native-image</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                                <configuration>
+                                    <systemProperties>
+                                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
+                                    </systemProperties>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>io.quarkus</groupId>
+                        <artifactId>quarkus-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>native-image</id>
+                                <goals>
+                                    <goal>native-image</goal>
+                                </goals>
+                                <configuration>
+                                    <reportErrorsAtRuntime>false</reportErrorsAtRuntime>
+                                    <cleanupServer>true</cleanupServer>
+                                    <enableHttpsUrlHandler>true</enableHttpsUrlHandler>
+                                    <enableServer>false</enableServer>
+                                    <dumpProxies>false</dumpProxies>
+                                    <graalvmHome>${graalvmHome}</graalvmHome>
+                                    <enableJni>true</enableJni>
+                                    <enableAllSecurityServices>true</enableAllSecurityServices>
+                                    <disableReports>true</disableReports>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/build/scripts/scaffold-integration-test.groovy b/build/scripts/scaffold-integration-test.groovy
new file mode 100644
index 0000000..d470be9
--- /dev/null
+++ b/build/scripts/scaffold-integration-test.groovy
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+import java.util.stream.Collectors
+import java.nio.charset.Charset
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+
+import freemarker.cache.ClassTemplateLoader
+import freemarker.cache.FileTemplateLoader
+import freemarker.cache.MultiTemplateLoader
+import freemarker.cache.TemplateLoader
+import freemarker.template.Configuration
+import freemarker.template.Template
+import freemarker.template.TemplateException
+import freemarker.template.TemplateExceptionHandler
+
+import io.quarkus.maven.CreateExtensionMojo.TemplateParams
+import io.quarkus.maven.utilities.PomTransformer
+import io.quarkus.maven.utilities.PomTransformer.Transformation
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+/* Keep in sync with the current file name */
+@groovy.transform.Field static final String currentScript = "scaffold-integration-test.groovy"
+@groovy.transform.Field static final Logger log = LoggerFactory.getLogger('scaffold-integration-test')
+final Path extensionsDir = project.basedir.toPath()
+final Path templatesDir = extensionsDir.resolve('../build/create-extension-templates')
+final String artifactIdBase = properties['quarkus.artifactIdBase']
+final Path itestDir = extensionsDir.resolve('../integration-tests/' + artifactIdBase)
+final Charset charset = StandardCharsets.UTF_8
+
+final nameBase = properties['quarkus.nameBase'] == null ? artifactIdBase.split(' ').collect{it.capitalize()}.join(' ') : artifactIdBase
+
+Files.createDirectories(itestDir)
+
+final Configuration cfg = new Configuration(Configuration.VERSION_2_3_28)
+cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
+cfg.setTemplateLoader(createTemplateLoader(templatesDir))
+cfg.setDefaultEncoding('UTF-8')
+cfg.setInterpolationSyntax(Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX)
+cfg.setTagSyntax(Configuration.SQUARE_BRACKET_TAG_SYNTAX)
+
+TemplateParams model = new TemplateParams()
+
+model.artifactIdBase = artifactIdBase
+model.artifactIdBaseCamelCase = toCapCamelCase(model.artifactIdBase)
+model.version = project.version
+
+model.nameBase = nameBase
+
+model.javaPackageBase = getJavaPackage('org.apache.camel.quarkus', 'component', artifactIdBase)
+final String javaPackageBasePath = model.javaPackageBase.replace('.', '/')
+
+evalTemplate(cfg, "integration-test-pom.xml", itestDir.resolve('pom.xml'), charset, model)
+evalTemplate(cfg, "TestResource.java", itestDir.resolve('src/main/java/' + javaPackageBasePath + '/it/'+ model.artifactIdBaseCamelCase + 'Resource.java'), charset, model)
+evalTemplate(cfg, "TestRouteBuilder.java", itestDir.resolve('src/main/java/' + javaPackageBasePath + '/it/'+ model.artifactIdBaseCamelCase + 'RouteBuilder.java'), charset, model)
+evalTemplate(cfg, "Test.java", itestDir.resolve('src/test/java/' + javaPackageBasePath + '/it/'+ model.artifactIdBaseCamelCase + 'Test.java'), charset, model)
+evalTemplate(cfg, "IT.java", itestDir.resolve('src/test/java/' + javaPackageBasePath + '/it/'+ model.artifactIdBaseCamelCase + 'IT.java'), charset, model)
+
+log.info(String.format("Adding module [%s] to [%s]", model.artifactIdBase, itestDir.resolve('../pom.xml')))
+new PomTransformer(itestDir.resolve('../pom.xml'), charset).transform(Transformation.addModule(model.artifactIdBase))
+
+static TemplateLoader createTemplateLoader(Path templatesDir) throws IOException {
+    return new MultiTemplateLoader([new FileTemplateLoader(templatesDir.toFile())] as TemplateLoader[])
+}
+
+static void evalTemplate(Configuration cfg, String templateUri, Path dest, Charset charset, TemplateParams model)
+        throws IOException, TemplateException {
+    log.info("Adding '{}'", dest)
+    final Template template = cfg.getTemplate(templateUri)
+    Files.createDirectories(dest.getParent())
+    Writer out
+    try {
+        out = Files.newBufferedWriter(dest)
+        template.process(model, out)
+    } finally {
+        out.close()
+    }
+}
+
+static String toCapCamelCase(String artifactIdBase) {
+    final StringBuilder sb = new StringBuilder(artifactIdBase.length())
+    for (String segment : artifactIdBase.split("[.\\-]+")) {
+        sb.append(Character.toUpperCase(segment.charAt(0)))
+        if (segment.length() > 1) {
+            sb.append(segment.substring(1))
+        }
+    }
+    return sb.toString()
+}
+
+static String getJavaPackage(String groupId, String javaPackageInfix, String artifactId) {
+    final Stack<String> segments = new Stack<>()
+    for (String segment : groupId.split("[.\\-]+")) {
+        if (segments.isEmpty() || !segments.peek().equals(segment)) {
+            segments.add(segment)
+        }
+    }
+    if (javaPackageInfix != null) {
+        for (String segment : javaPackageInfix.split("[.\\-]+")) {
+            segments.add(segment)
+        }
+    }
+    for (String segment : artifactId.split("[.\\-]+")) {
+        if (!segments.contains(segment)) {
+            segments.add(segment)
+        }
+    }
+    return segments.stream() //
+            .map{s -> s.toLowerCase(Locale.ROOT)} //
+            .map{s -> javax.lang.model.SourceVersion.isKeyword(s) ? s + "_" : s} //
+            .collect(Collectors.joining("."))
+}
+
diff --git a/docs/modules/ROOT/pages/contributor-guide.adoc b/docs/modules/ROOT/pages/contributor-guide.adoc
index a16e4f9..2db3ebd 100644
--- a/docs/modules/ROOT/pages/contributor-guide.adoc
+++ b/docs/modules/ROOT/pages/contributor-guide.adoc
@@ -62,7 +62,8 @@ mvn clean install -Dnative
 ----
 cd camel-quarkus
 cd extensions
-mvn quarkus:create-extension -N -Dquarkus.artifactIdBase=foo \
+mvn quarkus:create-extension groovy:execute@scaffold-integration-test -N \
+    -Dquarkus.artifactIdBase=foo \
     -Dquarkus.nameBase="Foo"
 ----
 +
@@ -76,22 +77,28 @@ The `artifactId` and artifact `name` prefixes and suffixes are added automatical
 The above sequence of commands does the following:
 * It creates three new Maven modules under the `extensions` directory: `camel-quarkus-foo-parent`, `camel-quarkus-foo`
   (a.k.a. the runtime module) and `camel-quarkus-foo-deployment`.
-* These three modules are liked where necessary:
+* These three modules are linked where necessary:
 ** `camel-quarkus-foo-parent` is added to the `<modules>` of `camel-quarkus-extensions`
 ** `camel-quarkus-foo` is added to the `<dependencyManagement>` of the runtime BOM (Bill of Materials) `poms/bom/pom.xml`
 ** `camel-quarkus-foo-deployment` is added to the `<dependencyManagement>` of the deployment BOM (Bill of Materials) `poms/bom-deployment/pom.xml`
-* It also creates a basic `FooProcessor` class in the deployment module.
+* It creates a basic `FooProcessor` class in the deployment module.
+* It also creates a stub of an integration test module under `integration-tests/foo`.
 +
-A Maven build performed immediately after generating the modules should pass flawlessly.
+A compilation performed immediately after generating the modules should pass flawlessly but running the tests will fail
+because the test project needs to get finished.
 +
 TIP: The `nameBase` parameter of the mojo is optional. If you do not specify it on the command line, the plugin will
 derive it from `artifactIdBase` by replacing dashes with spaces and uppercasing each token. So you may consider omitting
 explicit `nameBase` in some cases.
 
-6. Add an integration test under the `integration-tests` directory to make sure that your new extension works both in
-   the JVM mode and in the native mode.
+6. Complete the extension by adding dependencies to the runtime module. You probably want to add a dependency on
+   on the given Camel component - in our case `org.apache.camel:camel-foo`.
 
-7. In case of problems, consult the https://quarkus.io/guides/extension-authors-guide[Quarkus extension author's guide],
+7. Complete the integration test module under `integration-tests/foo`. Make sure you test both the consumer and the
+   producer of the component (if the component supports both). Make sure the tests are passing both in the JVM mode
+   (`mvn test`) and in the native mode (`mvn verify -Dnative`).
+
+8. In case of problems, consult the https://quarkus.io/guides/extension-authors-guide[Quarkus extension author's guide],
    ask for help in the given GitHub issue or via https://gitter.im/apache/camel-quarkus[Camel Quarkus chat].
 
 Good luck!
diff --git a/extensions/pom.xml b/extensions/pom.xml
index b78bf5a..7f77325 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -65,7 +65,7 @@
                 <artifactId>quarkus-maven-plugin</artifactId>
                 <inherited>false</inherited>
                 <!-- Setting for stubbing new extensions via
-                       mvn quarkus:create-extension -N -Dquarkus.artifactIdBase=my-new-extension
+                       mvn quarkus:create-extension groovy:execute@scaffold-integration-test -N -Dquarkus.artifactIdBase=my-new-extension
                 -->
                 <configuration>
                     <artifactIdPrefix>camel-quarkus-</artifactIdPrefix>
@@ -106,4 +106,43 @@
         </plugins>
     </build>
 
+    <profiles>
+        <profile>
+            <id>scaffold-integration-test</id>
+            <activation>
+                <property><name>quarkus.artifactIdBase</name></property>
+            </activation>
+
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.gmaven</groupId>
+                        <artifactId>groovy-maven-plugin</artifactId>
+                        <inherited>false</inherited>
+                        <executions>
+                            <execution>
+                                <id>scaffold-integration-test</id>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <phase>validate</phase>
+                                <configuration>
+                                    <source>file://${basedir}/../build/scripts/scaffold-integration-test.groovy</source>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <dependencies>
+                            <dependency>
+                                <groupId>io.quarkus</groupId>
+                                <artifactId>quarkus-maven-plugin</artifactId>
+                                <version>${quarkus.version}</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
 </project>