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 2018/10/02 11:51:59 UTC

[camel] branch master updated: CAMEL-12841: camel-restdsl-swagger:generate - Special case for Spring Boot with servlet component to generate CamelRestController support class to allow using root context-path and spring boot health check/actuators at the same time.

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


The following commit(s) were added to refs/heads/master by this push:
     new 0201758  CAMEL-12841: camel-restdsl-swagger:generate - Special case for Spring Boot with servlet component to generate CamelRestController support class to allow using root context-path and spring boot health check/actuators at the same time.
0201758 is described below

commit 020175876ce3ea58744fafcd0d273ea856d79878
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Oct 2 13:36:59 2018 +0200

    CAMEL-12841: camel-restdsl-swagger:generate - Special case for Spring Boot with servlet component to generate CamelRestController support class to allow using root context-path and spring boot health check/actuators at the same time.
---
 .../main/docs/camel-restdsl-swagger-plugin.adoc    |   7 ++
 .../generator/swagger/AbstractGenerateMojo.java    |  52 +++++++++-
 .../maven/generator/swagger/GenerateMojo.java      |  28 +++++-
 .../camel/generator/swagger/RestDslGenerator.java  |  20 ++++
 .../swagger/RestDslSourceCodeGenerator.java        |   6 +-
 .../generator/swagger/RestDslXmlGenerator.java     |   3 +
 .../SpringBootProjectSourceCodeGenerator.java      | 106 +++++++++++++++++++++
 .../PathSpringBootProjectSourceGeneratorTest.java  |  46 +++++++++
 .../generator/swagger/RestDslGeneratorTest.java    |   2 +-
 .../generator/swagger/RestDslXmlGeneratorTest.java |   2 +-
 .../test/resources/SpringBootRestController.txt    |  24 +++++
 .../resources/SwaggerPetstoreWithRestComponent.txt |   2 +-
 .../SwaggerPetstoreWithRestComponentXml.txt        |   2 +-
 13 files changed, 291 insertions(+), 9 deletions(-)

diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-restdsl-swagger-plugin.adoc b/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-restdsl-swagger-plugin.adoc
index f8f3ded..8f89e62 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-restdsl-swagger-plugin.adoc
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-restdsl-swagger-plugin.adoc
@@ -69,6 +69,13 @@ in the `<configuration>` tag.
 | `restConfiguration` | `true` | Whether to include generation of the rest configuration with detected rest component to be used. |
 |========================================
 
+=== Spring Boot Project with Servlet component
+
+If the Maven project is a Spring Boot project and `restConfiguration` is enabled and the servlet component
+is being used as REST component, then this plugin will
+autodetect the package name where the `@SpringBootApplication` main class is located, and use the same
+package name for generating Rest DSL source code and a needed `CamelRestController` support class.
+
 == camel-restdsl-swagger:generate-with-dto
 
 Works as `generate` goal but also generates DTO model classes by automatic executing
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
index bde21a3..8dbbde7 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
@@ -17,16 +17,20 @@
 package org.apache.camel.maven.generator.swagger;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 
 import org.apache.camel.generator.swagger.DestinationGenerator;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
@@ -204,8 +208,54 @@ abstract class AbstractGenerateMojo extends AbstractMojo {
 
     protected String detectCamelVersionFromClasspath() {
         return mavenProject.getDependencies().stream().filter(
-                d -> "org.apache.camel".equals(d.getGroupId()) && ObjectHelper.isNotEmpty(d.getVersion()))
+            d -> "org.apache.camel".equals(d.getGroupId()) && ObjectHelper.isNotEmpty(d.getVersion()))
             .findFirst().map(Dependency::getVersion).orElse(null);
     }
 
+    protected String detectSpringBootMainPackage() throws IOException {
+        for (String src : mavenProject.getCompileSourceRoots()) {
+            String d = findSpringSpringBootPackage(new File(src));
+            if (d != null) {
+                return d;
+            }
+        }
+        return null;
+    }
+
+    protected String findSpringSpringBootPackage(File dir) throws IOException {
+        File[] files = dir.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.getName().endsWith(".java")) {
+                    String content = IOHelper.loadText(new FileInputStream(file));
+                    if (content.contains("@SpringBootApplication")) {
+                        return grabPackageName(content);
+                    }
+                } else if (file.isDirectory()) {
+                    String packageName = findSpringSpringBootPackage(file);
+                    if (packageName != null) {
+                        return packageName;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    protected String grabPackageName(String content) {
+        String[] lines = content.split("\\n");
+        for (String line : lines) {
+            line = line.trim();
+            if (line.startsWith("package ")) {
+                line = line.substring(8);
+                line = line.trim();
+                if (line.endsWith(";")) {
+                    line = line.substring(0, line.length() - 1);
+                }
+                return line;
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
index d8e62ed..33e0173 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
@@ -25,6 +25,7 @@ import io.swagger.parser.SwaggerParser;
 import org.apache.camel.generator.swagger.DestinationGenerator;
 import org.apache.camel.generator.swagger.RestDslGenerator;
 import org.apache.camel.generator.swagger.RestDslSourceCodeGenerator;
+import org.apache.camel.generator.swagger.SpringBootProjectSourceCodeGenerator;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.LifecyclePhase;
@@ -87,12 +88,16 @@ public class GenerateMojo extends AbstractGenerateMojo {
             generator.withDestinationGenerator(destinationGeneratorObject);
         }
 
+        final Path outputPath = new File(outputDirectory).toPath();
+
         if (restConfiguration) {
             String comp = detectRestComponentFromClasspath();
             if (comp != null) {
                 getLog().info("Detected Camel Rest component from classpath: " + comp);
                 generator.withRestComponent(comp);
             } else {
+                comp = "servlet";
+
                 // is it spring boot?
                 String aid = "camel-servlet";
                 if (detectSpringBootFromClasspath()) {
@@ -113,14 +118,32 @@ public class GenerateMojo extends AbstractGenerateMojo {
 
                 generator.withRestComponent("servlet");
             }
+
+            // if its a spring boot project and we use servlet then we should generate additional source code
+            if (detectSpringBootFromClasspath() && "servlet".equals(comp)) {
+                try {
+                    String pName = detectSpringBootMainPackage();
+                    if (pName != null) {
+                        packageName = pName;
+                        generator.withPackageName(packageName);
+                        getLog().info("Detected @SpringBootApplication, and will be using its package name: " + packageName);
+                    }
+                    getLog().info("Generating Camel Rest Controller source with package name " + packageName + " in source directory: " + outputPath);
+                    SpringBootProjectSourceCodeGenerator.generator().withPackageName(packageName).generate(outputPath);
+                    // the Camel Rest Controller allows to use root as context-path
+                    generator.withRestContextPath("/");
+                } catch (final IOException e) {
+                    throw new MojoExecutionException(
+                        "Unable to generate Camel Rest Controller source due " + e.getMessage(), e);
+                }
+            }
         }
 
         if (detectSpringBootFromClasspath()) {
             generator.asSpringComponent();
+            generator.asSpringBootProject();
         }
 
-        final Path outputPath = new File(outputDirectory).toPath();
-
         try {
             getLog().info("Generating Camel DSL source in directory: " + outputPath);
             generator.generate(outputPath);
@@ -130,5 +153,4 @@ public class GenerateMojo extends AbstractGenerateMojo {
         }
     }
 
-
 }
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
index cc21ec6..a96f2aa 100644
--- a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
@@ -35,7 +35,9 @@ public abstract class RestDslGenerator<G> {
     DestinationGenerator destinationGenerator = new DirectToOperationId();
     OperationFilter filter = new OperationFilter();
     String restComponent;
+    String restContextPath;
     boolean springComponent;
+    boolean springBootProject;
 
     RestDslGenerator(final Swagger swagger) {
         this.swagger = notNull(swagger, "swagger");
@@ -82,6 +84,15 @@ public abstract class RestDslGenerator<G> {
         return that;
     }
 
+    public G withRestContextPath(String contextPath) {
+        this.restContextPath = contextPath;
+
+        @SuppressWarnings("unchecked")
+        final G that = (G) this;
+
+        return that;
+    }
+
     public G asSpringComponent() {
         this.springComponent = true;
 
@@ -91,6 +102,15 @@ public abstract class RestDslGenerator<G> {
         return that;
     }
 
+    public G asSpringBootProject() {
+        this.springBootProject = true;
+
+        @SuppressWarnings("unchecked")
+        final G that = (G) this;
+
+        return that;
+    }
+
     public static RestDslSourceCodeGenerator<Appendable> toAppendable(final Swagger swagger) {
         return new AppendableGenerator(swagger);
     }
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
index c534e66..953c445 100644
--- a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
@@ -104,7 +104,11 @@ public abstract class RestDslSourceCodeGenerator<T> extends RestDslGenerator<Res
 
         if (restComponent != null) {
             configure.addCode("\n");
-            configure.addCode("restConfiguration().component(\"" + restComponent + "\");\n\n");
+            configure.addCode("restConfiguration().component(\"" + restComponent + "\")");
+            if (restContextPath != null) {
+                configure.addCode(".contextPath(\"" + restContextPath + "\")");
+            }
+            configure.addCode(";\n\n");
         }
 
         final PathVisitor<MethodSpec> restDslStatement = new PathVisitor<>(emitter, filter, destinationGenerator());
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java
index d57d340..cf74fd3 100644
--- a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java
@@ -52,6 +52,9 @@ public class RestDslXmlGenerator extends RestDslGenerator<RestDslXmlGenerator> {
 
         if (restComponent != null) {
             String extra = "<restConfiguration component=\"" + restComponent + "\"/>";
+            if (restContextPath != null) {
+                extra = "<restConfiguration component=\"" + restComponent + "\" contextPath=\"" + restContextPath + "\"/>";
+            }
             xml = xml.replaceFirst("<rest>", extra + "\n    <rest>");
         }
 
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/SpringBootProjectSourceCodeGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/SpringBootProjectSourceCodeGenerator.java
new file mode 100644
index 0000000..44a184d
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/SpringBootProjectSourceCodeGenerator.java
@@ -0,0 +1,106 @@
+/**
+ * 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 org.apache.camel.generator.swagger;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import javax.annotation.Generated;
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.camel.util.ObjectHelper;
+
+import static org.apache.camel.util.StringHelper.notEmpty;
+
+public class SpringBootProjectSourceCodeGenerator {
+
+    private static final String DEFAULT_INDENT = "    ";
+
+    private String indent = DEFAULT_INDENT;
+
+    private String packageName;
+
+    public void generate(Path destination) throws IOException {
+        final JavaFile javaFile = generateSourceCode();
+
+        javaFile.writeTo(destination);
+    }
+
+    public SpringBootProjectSourceCodeGenerator withIndent(final String indent) {
+        this.indent = ObjectHelper.notNull(indent, "indent");
+        return this;
+    }
+
+    public SpringBootProjectSourceCodeGenerator withPackageName(final String packageName) {
+        notEmpty(packageName, "packageName");
+        this.packageName = packageName;
+        return this;
+    }
+
+    JavaFile generateSourceCode() {
+        notEmpty(packageName, "packageName");
+
+        final MethodSpec methodSpec = generateRestMethod();
+
+        final String classNameToUse = "CamelRestController";
+
+        final AnnotationSpec.Builder generatedAnnotation = AnnotationSpec.builder(Generated.class).addMember("value",
+            "$S", getClass().getName());
+        final AnnotationSpec.Builder restAnnotation = AnnotationSpec.builder(ClassName.bestGuess("org.springframework.web.bind.annotation.RestController"));
+
+        TypeSpec.Builder builder = TypeSpec.classBuilder(classNameToUse)
+            .addModifiers(Modifier.PUBLIC, Modifier.FINAL).addMethod(methodSpec)
+            .addAnnotation(generatedAnnotation.build())
+            .addAnnotation(restAnnotation.build())
+            .addJavadoc("Forward requests to the Camel servlet so it can service REST requests.\n");
+        TypeSpec generatedRestController = builder.build();
+
+        return JavaFile.builder(packageName, generatedRestController).indent(indent).build();
+    }
+
+    MethodSpec generateRestMethod() {
+        ClassName req = ClassName.bestGuess("javax.servlet.http.HttpServletRequest");
+        ClassName res = ClassName.bestGuess("javax.servlet.http.HttpServletResponse");
+
+        final AnnotationSpec.Builder reqAnnotation = AnnotationSpec.builder(ClassName.bestGuess("org.springframework.web.bind.annotation.RequestMapping"))
+            .addMember("value", "\"/**\"");
+
+        final MethodSpec.Builder forward = MethodSpec.methodBuilder("camelServlet").addModifiers(Modifier.PUBLIC)
+            .addParameter(req, "request")
+            .addParameter(res, "response")
+            .addAnnotation(reqAnnotation.build())
+            .returns(void.class);
+
+        forward.addCode("try {\n");
+        forward.addCode("    String path = request.getRequestURI();\n");
+        forward.addCode("    request.getServletContext().getRequestDispatcher(\"/camel/\" + path).forward(request, response);\n");
+        forward.addCode("} catch (Exception e) {\n");
+        forward.addCode("    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\n");
+        forward.addCode("}\n");
+
+        return forward.build();
+    }
+
+    public static SpringBootProjectSourceCodeGenerator generator() {
+        return new SpringBootProjectSourceCodeGenerator();
+    }
+
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/PathSpringBootProjectSourceGeneratorTest.java b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/PathSpringBootProjectSourceGeneratorTest.java
new file mode 100644
index 0000000..2d57a1f
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/PathSpringBootProjectSourceGeneratorTest.java
@@ -0,0 +1,46 @@
+/**
+ * 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 org.apache.camel.generator.swagger;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PathSpringBootProjectSourceGeneratorTest {
+
+    @Test
+    public void shouldGenerateSourceCodeWithDefaults() throws IOException, URISyntaxException {
+        Path path = new File("target/generated-sources").toPath();
+        SpringBootProjectSourceCodeGenerator.generator().withPackageName("com.foo").generate(path);
+        final String generatedContent = new String(Files.readAllBytes(Paths.get("target/generated-sources/com/foo/CamelRestController.java")), StandardCharsets.UTF_8);
+
+        final URI file = PathSpringBootProjectSourceGeneratorTest.class.getResource("/SpringBootRestController.txt").toURI();
+        final String expectedContent = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
+
+        assertThat(generatedContent).isEqualTo(expectedContent);
+    }
+
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslGeneratorTest.java b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslGeneratorTest.java
index c8dcc09..579b242 100644
--- a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslGeneratorTest.java
+++ b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslGeneratorTest.java
@@ -65,7 +65,7 @@ public class RestDslGeneratorTest {
     public void shouldGenerateSourceCodeWithRestComponent() throws IOException, URISyntaxException {
         final StringBuilder code = new StringBuilder();
 
-        RestDslGenerator.toAppendable(swagger).withGeneratedTime(generated).withRestComponent("servlet").generate(code);
+        RestDslGenerator.toAppendable(swagger).withGeneratedTime(generated).withRestComponent("servlet").withRestContextPath("/").generate(code);
 
         final URI file = RestDslGeneratorTest.class.getResource("/SwaggerPetstoreWithRestComponent.txt").toURI();
         final String expectedContent = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
diff --git a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java
index 2e45203..4ad6718 100644
--- a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java
+++ b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java
@@ -67,7 +67,7 @@ public class RestDslXmlGeneratorTest {
     public void shouldGenerateXmlWithRestComponent() throws Exception {
         final CamelContext context = new DefaultCamelContext();
 
-        final String xml = RestDslGenerator.toXml(swagger).withRestComponent("servlet").generate(context);
+        final String xml = RestDslGenerator.toXml(swagger).withRestComponent("servlet").withRestContextPath("/foo").generate(context);
 
         final URI file = RestDslGeneratorTest.class.getResource("/SwaggerPetstoreWithRestComponentXml.txt").toURI();
         final String expectedContent = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
diff --git a/tooling/swagger-rest-dsl-generator/src/test/resources/SpringBootRestController.txt b/tooling/swagger-rest-dsl-generator/src/test/resources/SpringBootRestController.txt
new file mode 100644
index 0000000..0a54740
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/test/resources/SpringBootRestController.txt
@@ -0,0 +1,24 @@
+package com.foo;
+
+import javax.annotation.Generated;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Forward requests to the Camel servlet so it can service REST requests.
+ */
+@Generated("org.apache.camel.generator.swagger.SpringBootProjectSourceCodeGenerator")
+@RestController
+public final class CamelRestController {
+    @RequestMapping("/**")
+    public void camelServlet(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            String path = request.getRequestURI();
+            request.getServletContext().getRequestDispatcher("/camel/" + path).forward(request, response);
+        } catch (Exception e) {
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+    }
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponent.txt b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponent.txt
index 6ccda76..fbe598b 100644
--- a/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponent.txt
+++ b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponent.txt
@@ -15,7 +15,7 @@ public final class SwaggerPetstore extends RouteBuilder {
      */
     public void configure() {
 
-        restConfiguration().component("servlet");
+        restConfiguration().component("servlet").contextPath("/");
 
         rest()
             .put("/pet")
diff --git a/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponentXml.txt b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponentXml.txt
index bcc5cd5..85bec26 100644
--- a/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponentXml.txt
+++ b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreWithRestComponentXml.txt
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <rests xmlns="http://camel.apache.org/schema/spring">
-    <restConfiguration component="servlet"/>
+    <restConfiguration component="servlet" contextPath="/foo"/>
     <rest>
         <put consumes="application/json,application/xml" id="updatePet" produces="application/xml,application/json" uri="/pet">
             <param description="Pet object that needs to be added to the store" name="body" required="true" type="body"/>