You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2019/10/07 17:25:41 UTC

[camel-quarkus] branch master updated: port rest-json quickstart to camel-quarkus

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

lburgazzoli 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 57be755  port rest-json quickstart to camel-quarkus
57be755 is described below

commit 57be75573cb94a3a8e6be7ed27e2945d9f7cf6c7
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Mon Oct 7 13:45:15 2019 +0200

    port rest-json quickstart to camel-quarkus
---
 examples/pom.xml                                   | 38 +++++++++
 examples/rest-json/README.adoc                     | 20 +++++
 .../servlet => examples/rest-json}/pom.xml         | 40 +++++----
 .../src/main/java/org/acme/rest/json/Fruit.java    | 67 +++++++++++++++
 .../src/main/java/org/acme/rest/json/Legume.java   | 67 +++++++++++++++
 .../src/main/java/org/acme/rest/json/Routes.java   | 64 ++++++++++++++
 .../main/resources/META-INF/resources/fruits.html  | 98 ++++++++++++++++++++++
 .../main/resources/META-INF/resources/legumes.html | 61 ++++++++++++++
 .../src/main/resources/application.properties      | 34 ++++++++
 .../java/org/acme/rest/json/FruitResourceIT.java   | 23 +++++
 .../java/org/acme/rest/json/FruitResourceTest.java | 56 +++++++++++++
 .../java/org/acme/rest/json/LegumeResourceIT.java  | 23 +++++
 .../org/acme/rest/json/LegumeResourceTest.java     | 39 +++++++++
 integration-tests/servlet/pom.xml                  | 18 +---
 pom.xml                                            |  1 +
 poms/bom/pom.xml                                   |  5 ++
 16 files changed, 623 insertions(+), 31 deletions(-)

diff --git a/examples/pom.xml b/examples/pom.xml
new file mode 100644
index 0000000..6d42d4c
--- /dev/null
+++ b/examples/pom.xml
@@ -0,0 +1,38 @@
+<?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/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-parent</artifactId>
+        <version>0.2.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-quarkus-examples</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Camel Quarkus :: Examples</name>
+
+    <modules>
+        <module>rest-json</module>
+    </modules>
+
+</project>
diff --git a/examples/rest-json/README.adoc b/examples/rest-json/README.adoc
new file mode 100644
index 0000000..63f8c8b
--- /dev/null
+++ b/examples/rest-json/README.adoc
@@ -0,0 +1,20 @@
+# rest-json
+
+
+This example is a port of Quarkus' quickstart https://github.com/quarkusio/quarkus-quickstarts/blob/master/rest-json[rest-json] to Camel.
+
+
+To run it:
+
+[source]
+----
+$ mvn clean compile quarkus:dev -DnoDeps
+----
+
+Then point your browser to one of the endpoints:
+
+[source]
+----
+http://localhost:8080/fruits.html
+http://localhost:8080/legumes.html
+----
\ No newline at end of file
diff --git a/integration-tests/servlet/pom.xml b/examples/rest-json/pom.xml
similarity index 82%
copy from integration-tests/servlet/pom.xml
copy to examples/rest-json/pom.xml
index a139099..1420885 100644
--- a/integration-tests/servlet/pom.xml
+++ b/examples/rest-json/pom.xml
@@ -20,16 +20,15 @@
 <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">
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <!-- Test that the BOM can serve as parent for user apps, see also https://github.com/apache/camel-quarkus/issues/118 -->
-        <artifactId>camel-quarkus-bom</artifactId>
+        <artifactId>camel-quarkus-examples</artifactId>
         <version>0.2.1-SNAPSHOT</version>
-        <relativePath>../../poms/bom/pom.xml</relativePath>
     </parent>
+
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>camel-quarkus-integration-test-servlet</artifactId>
-    <name>Camel Quarkus :: Integration Tests :: Servlet</name>
-    <description>Integration tests for Camel Servlet component</description>
+    <artifactId>camel-quarkus-examples-rest-json</artifactId>
+    <name>Camel Quarkus :: Examples :: Rest Json</name>
+    <description>Camel Quarkus Example :: Rest Json</description>
 
     <properties>
         <!--
@@ -42,21 +41,33 @@
         <native-image.container-runtime>docker</native-image.container-runtime>
     </properties>
 
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-bom</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-servlet</artifactId>
+            <artifactId>camel-quarkus-platform-http</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-rest</artifactId>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jackson</artifactId>
         </dependency>
+
         <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-core-cloud</artifactId>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy</artifactId>
         </dependency>
 
-
         <!-- test dependencies -->
         <dependency>
             <groupId>io.quarkus</groupId>
@@ -77,6 +88,7 @@
                 <artifactId>quarkus-maven-plugin</artifactId>
                 <executions>
                     <execution>
+                        <id>build</id>
                         <goals>
                             <goal>build</goal>
                         </goals>
@@ -123,11 +135,9 @@
                                     <goal>native-image</goal>
                                 </goals>
                                 <configuration>
+                                    <enableServer>false</enableServer>
                                     <cleanupServer>true</cleanupServer>
                                     <enableHttpUrlHandler>true</enableHttpUrlHandler>
-                                    <enableJni>false</enableJni>
-                                    <debugBuildProcess>false</debugBuildProcess>
-                                    <disableReports>true</disableReports>
                                 </configuration>
                             </execution>
                         </executions>
diff --git a/examples/rest-json/src/main/java/org/acme/rest/json/Fruit.java b/examples/rest-json/src/main/java/org/acme/rest/json/Fruit.java
new file mode 100644
index 0000000..29349f0
--- /dev/null
+++ b/examples/rest-json/src/main/java/org/acme/rest/json/Fruit.java
@@ -0,0 +1,67 @@
+/*
+ * 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.acme.rest.json;
+
+import java.util.Objects;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class Fruit {
+    private String name;
+    private String description;
+
+    public Fruit() {
+    }
+
+    public Fruit(String name, String description) {
+        this.name = name;
+        this.description = description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Fruit)) {
+            return false;
+        }
+
+        Fruit other = (Fruit) obj;
+
+        return Objects.equals(other.name, this.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.name);
+    }
+}
diff --git a/examples/rest-json/src/main/java/org/acme/rest/json/Legume.java b/examples/rest-json/src/main/java/org/acme/rest/json/Legume.java
new file mode 100644
index 0000000..b72a880
--- /dev/null
+++ b/examples/rest-json/src/main/java/org/acme/rest/json/Legume.java
@@ -0,0 +1,67 @@
+/*
+ * 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.acme.rest.json;
+
+import java.util.Objects;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class Legume {
+    private String name;
+    private String description;
+
+    public Legume() {
+    }
+
+    public Legume(String name, String description) {
+        this.name = name;
+        this.description = description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Legume)) {
+            return false;
+        }
+
+        Legume other = (Legume) obj;
+
+        return Objects.equals(other.name, this.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.name);
+    }
+}
diff --git a/examples/rest-json/src/main/java/org/acme/rest/json/Routes.java b/examples/rest-json/src/main/java/org/acme/rest/json/Routes.java
new file mode 100644
index 0000000..cc39afe
--- /dev/null
+++ b/examples/rest-json/src/main/java/org/acme/rest/json/Routes.java
@@ -0,0 +1,64 @@
+/*
+ * 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.acme.rest.json;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.dataformat.JsonLibrary;
+
+public class Routes extends RouteBuilder {
+    private final Set<Fruit> fruits;
+    private final Set<Legume> legumes;
+
+    public Routes() {
+        this.fruits =  Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>()));
+        this.fruits.add(new Fruit("Apple", "Winter fruit"));
+        this.fruits.add(new Fruit("Pineapple", "Tropical fruit"));
+
+        this.legumes = Collections.synchronizedSet(new LinkedHashSet<>());
+        this.legumes.add(new Legume("Carrot", "Root vegetable, usually orange"));
+        this.legumes.add(new Legume("Zucchini", "Summer squash"));
+    }
+
+    @Override
+    public void configure() throws Exception {
+        from("platform-http:/legumes?httpMethodRestrict=GET")
+            .setBody().constant(legumes)
+            .marshal().json();
+
+        from("platform-http:/fruits?httpMethodRestrict=GET,POST")
+            .choice()
+                .when(simple("${header.CamelHttpMethod} == 'GET'"))
+                    .setBody()
+                        .constant(fruits)
+                    .endChoice()
+                .when(simple("${header.CamelHttpMethod} == 'POST'"))
+                    .unmarshal()
+                        .json(JsonLibrary.Jackson, Fruit.class)
+                    .process()
+                        .body(Fruit.class, fruits::add)
+                    .setBody()
+                        .constant(fruits)
+                    .endChoice()
+            .end()
+            .marshal().json();
+    }
+}
diff --git a/examples/rest-json/src/main/resources/META-INF/resources/fruits.html b/examples/rest-json/src/main/resources/META-INF/resources/fruits.html
new file mode 100644
index 0000000..3e25016
--- /dev/null
+++ b/examples/rest-json/src/main/resources/META-INF/resources/fruits.html
@@ -0,0 +1,98 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <title>Fruit REST service</title>
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/wingcss/0.1.8/wing.min.css"/>
+    <!-- Load AngularJS -->
+    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    <script type="text/javascript">
+      var app = angular.module("FruitManagement", []);
+
+      //Controller Part
+      app.controller("FruitManagementController", function ($scope, $http) {
+
+        //Initialize page with default data which is blank in this example
+        $scope.fruits = [];
+
+        $scope.form = {
+          name: "",
+          description: ""
+        };
+
+        //Now load the data from server
+        _refreshPageData();
+
+        //HTTP POST methods for add fruits
+        $scope.add = function () {
+          var data = { "name": $scope.form.name, "description": $scope.form.description };
+
+          $http({
+            method: "POST",
+            url: '/fruits',
+            data: angular.toJson(data),
+            headers: {
+              'Content-Type': 'application/json'
+            }
+          }).then(_success, _error);
+        };
+
+        /* Private Methods */
+        //HTTP GET- get all fruits collection
+        function _refreshPageData() {
+          $http({
+            method: 'GET',
+            url: '/fruits'
+          }).then(function successCallback(response) {
+            $scope.fruits = response.data;
+          }, function errorCallback(response) {
+            console.log(response.statusText);
+          });
+        }
+
+        function _success(response) {
+          _refreshPageData();
+          _clearForm();
+        }
+
+        function _error(response) {
+          alert(response.data.message || response.statusText);
+        }
+
+        //Clear the form
+        function _clearForm() {
+          $scope.form.name = "";
+          $scope.form.description = "";
+        }
+      });
+    </script>
+</head>
+<body ng-app="FruitManagement" ng-controller="FruitManagementController">
+
+<div class="container">
+    <h1>REST Service - Fruit</h1>
+
+    <h3>Add a fruit</h3>
+    <form ng-submit="add()">
+        <div class="row">
+            <div class="col-6"><input type="text" placeholder="Name" ng-model="form.name" size="60"/></div>
+        </div>
+        <div class="row">
+            <div class="col-6"><input type="text" placeholder="Description" ng-model="form.description" size="60"/></div>
+        </div>
+        <input type="submit" value="Save"/>
+    </form>
+
+    <h3>Fruit List</h3>
+    <div class="row">
+        <div class="col-4">Name</div>
+        <div class="col-8">Description</div>
+    </div>
+    <div class="row" ng-repeat="fruit in fruits">
+        <div class="col-4">{{ fruit.name }}</div>
+        <div class="col-8">{{ fruit.description }}</div>
+    </div>
+</div>
+
+</body>
+</html>
diff --git a/examples/rest-json/src/main/resources/META-INF/resources/legumes.html b/examples/rest-json/src/main/resources/META-INF/resources/legumes.html
new file mode 100644
index 0000000..42a685a
--- /dev/null
+++ b/examples/rest-json/src/main/resources/META-INF/resources/legumes.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <title>Legume REST service</title>
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/wingcss/0.1.8/wing.min.css"/>
+    <!-- Load AngularJS -->
+    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    <script type="text/javascript">
+      var app = angular.module("LegumeManagement", []);
+
+      //Controller Part
+      app.controller("LegumeManagementController", function ($scope, $http) {
+
+        //Initialize page with default data which is blank in this example
+        $scope.legumes = [];
+
+        //Now load the data from server
+        _refreshPageData();
+
+        /* Private Methods */
+        //HTTP GET- get all legumes collection
+        function _refreshPageData() {
+          $http({
+            method: 'GET',
+            url: '/legumes'
+          }).then(function successCallback(response) {
+            $scope.legumes = response.data;
+          }, function errorCallback(response) {
+            console.log(response.statusText);
+          });
+        }
+
+        function _success(response) {
+          _refreshPageData();
+        }
+
+        function _error(response) {
+          alert(response.data.message || response.statusText);
+        }
+      });
+    </script>
+</head>
+<body ng-app="LegumeManagement" ng-controller="LegumeManagementController">
+
+<div class="container">
+    <h1>REST Service - Legume</h1>
+
+    <h3>Legume List</h3>
+    <div class="row">
+        <div class="col-4">Name</div>
+        <div class="col-8">Description</div>
+    </div>
+    <div class="row" ng-repeat="legume in legumes">
+        <div class="col-4">{{ legume.name }}</div>
+        <div class="col-8">{{ legume.description }}</div>
+    </div>
+</div>
+
+</body>
+</html>
diff --git a/examples/rest-json/src/main/resources/application.properties b/examples/rest-json/src/main/resources/application.properties
new file mode 100644
index 0000000..3098410
--- /dev/null
+++ b/examples/rest-json/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.
+## ---------------------------------------------------------------------------
+#
+# Quarkus
+#
+quarkus.log.file.enable = false
+quarkus.ssl.native=true
+
+#
+# Quarkus :: Camel
+#
+quarkus.camel.disable-xml=true
+quarkus.camel.disable-jaxb=true        
+quarkus.camel.dump-routes=true
+
+#
+# Camel
+#
+camel.context.name = quarkus-camel-example-rest-json
+
diff --git a/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceIT.java b/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceIT.java
new file mode 100644
index 0000000..d36cb4b
--- /dev/null
+++ b/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.acme.rest.json;
+
+import io.quarkus.test.junit.SubstrateTest;
+
+@SubstrateTest
+public class FruitResourceIT extends FruitResourceTest {
+}
\ No newline at end of file
diff --git a/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceTest.java b/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceTest.java
new file mode 100644
index 0000000..fdd17fb
--- /dev/null
+++ b/examples/rest-json/src/test/java/org/acme/rest/json/FruitResourceTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.acme.rest.json;
+
+import javax.ws.rs.core.MediaType;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+
+@QuarkusTest
+public class FruitResourceTest {
+
+    @Test
+    public void test() {
+        given()
+          .when().get("/fruits")
+          .then()
+             .statusCode(200)
+             .body(
+                "$.size()", is(2),
+                "name", containsInAnyOrder("Apple", "Pineapple"),
+                "description", containsInAnyOrder("Winter fruit", "Tropical fruit")
+             );
+
+        given()
+            .body("{\"name\": \"Pear\", \"description\": \"Winter fruit\"}")
+            .header("Content-Type", MediaType.APPLICATION_JSON)
+        .when()
+            .post("/fruits")
+        .then()
+            .statusCode(200)
+            .body(
+                "$.size()", is(3),
+                "name", containsInAnyOrder("Apple", "Pineapple", "Pear"),
+                "description", containsInAnyOrder("Winter fruit", "Tropical fruit", "Winter fruit")
+            );
+    }
+}
diff --git a/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceIT.java b/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceIT.java
new file mode 100644
index 0000000..ce0b3c8
--- /dev/null
+++ b/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.acme.rest.json;
+
+import io.quarkus.test.junit.SubstrateTest;
+
+@SubstrateTest
+public class LegumeResourceIT extends LegumeResourceTest {
+}
\ No newline at end of file
diff --git a/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceTest.java b/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceTest.java
new file mode 100644
index 0000000..c0b5eb0
--- /dev/null
+++ b/examples/rest-json/src/test/java/org/acme/rest/json/LegumeResourceTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.acme.rest.json;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+
+@QuarkusTest
+public class LegumeResourceTest {
+
+    @Test
+    public void testList() {
+        given()
+          .when().get("/legumes")
+          .then()
+             .statusCode(200)
+             .body("$.size()", is(2),
+                     "name", containsInAnyOrder("Carrot", "Zucchini"),
+                     "description", containsInAnyOrder("Root vegetable, usually orange", "Summer squash"));
+    }
+}
diff --git a/integration-tests/servlet/pom.xml b/integration-tests/servlet/pom.xml
index a139099..38acab5 100644
--- a/integration-tests/servlet/pom.xml
+++ b/integration-tests/servlet/pom.xml
@@ -18,30 +18,17 @@
 
 -->
 <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>
-        <!-- Test that the BOM can serve as parent for user apps, see also https://github.com/apache/camel-quarkus/issues/118 -->
-        <artifactId>camel-quarkus-bom</artifactId>
+        <artifactId>camel-quarkus-integration-tests</artifactId>
         <version>0.2.1-SNAPSHOT</version>
-        <relativePath>../../poms/bom/pom.xml</relativePath>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
 
     <artifactId>camel-quarkus-integration-test-servlet</artifactId>
     <name>Camel Quarkus :: Integration Tests :: Servlet</name>
     <description>Integration tests for Camel Servlet component</description>
 
-    <properties>
-        <!--
-            Make quarkus use docker by default as native-image does not
-            work anymore due to a Fedora upgrade
-
-            See https://github.com/oracle/graal/issues/1582
-         -->
-        <native-image.docker-build>true</native-image.docker-build>
-        <native-image.container-runtime>docker</native-image.container-runtime>
-    </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
@@ -56,7 +43,6 @@
             <artifactId>camel-quarkus-core-cloud</artifactId>
         </dependency>
 
-
         <!-- test dependencies -->
         <dependency>
             <groupId>io.quarkus</groupId>
diff --git a/pom.xml b/pom.xml
index ae57298..f93af19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,7 @@
         <module>poms/build-parent</module>
         <module>extensions</module>
         <module>integration-tests</module>
+        <module>examples</module>
         <module>docs</module>
     </modules>
 
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 7930c40..1cecddf 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -147,6 +147,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
+                <artifactId>camel-jackson</artifactId>
+                <version>${camel.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
                 <artifactId>camel-log</artifactId>
                 <version>${camel.version}</version>
             </dependency>