You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2020/12/09 10:04:12 UTC

[camel-quarkus] branch camel-master updated (26b660d -> 0b4216a)

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

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


 discard 26b660d  Remove Camel AS2 configuration class reflection registration
 discard 992a671  BigQuery native support
 discard b646442  Google PubSub native support
 discard b90b6f8  [Camel 3.7] JSON-B data format support
 discard bd76d33  Upgrade to Camel 3.7.0
     add 58db89a  Updated CHANGELOG.md
     add db5728f  nats: Explicited each classpath resource mapping checks for finer grained logging in case of issue #2061
     add 2a3c0b7  Polish how we pass -Djavax.net.ssl.trustStore to the Solr test #2029
     add 3b06ef3  Updated CHANGELOG.md
     add 8f8a65c  Upgrade to Quarkus 1.10.3.Final
     new 5b86976  Upgrade to Camel 3.7.0
     new bfd1833  [Camel 3.7] JSON-B data format support
     new aef9ea8  Google PubSub native support
     new 1839582  BigQuery native support
     new ac39f03  Remove Camel AS2 configuration class reflection registration
     new 0b4216a  CSimple language support #2036

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (26b660d)
            \
             N -- N -- N   refs/heads/camel-master (0b4216a)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 6 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.


Summary of changes:
 CHANGELOG.md                                       |   7 +-
 .../ROOT/pages/reference/extensions/core.adoc      |   6 +
 .../zipkin.adoc => components/vertx-kafka.adoc}    |   0
 extensions-core/core/deployment/pom.xml            |  16 +
 .../CSimpleRouteDefinitionProcessor.java           | 354 +++++++++++++++++++++
 .../LanguageExpressionContentHandler.java          | 122 +++++++
 .../spi/CSimpleExpressionSourceBuildItem.java      |  58 ++++
 .../spi/CompiledCSimpleExpressionBuildItem.java    |  32 +-
 .../core/runtime/src/main/adoc/limitations.adoc    |  17 +
 .../quarkus/core/CSimpleLanguageRecorder.java      |  24 +-
 .../org/apache/camel/quarkus/core/CamelConfig.java |  18 ++
 .../main/deployment/CSimpleXmlProcessor.java       | 127 ++++++++
 .../quarkus/test/ExtendDefaultTrustStore.java      |  87 +++++
 .../camel/quarkus/test/TrustStoreResource.java     |  10 +-
 integration-tests/core/pom.xml                     |  42 +++
 .../apache/camel/quarkus/core/CoreResource.java    |  14 +
 .../org/apache/camel/quarkus/core/CoreRoutes.java  |   3 +
 .../org/apache/camel/quarkus/core/CoreTest.java    |  12 +
 .../camel/quarkus/main/CoreMainXmlIoResource.java  |   8 +
 .../src/main/resources/routes/my-routes.xml        |   7 +
 .../camel/quarkus/main/CoreMainXmlIoTest.java      |  13 +-
 .../quarkus/component/nats/it/NatsRoutes.java      |   2 +-
 .../component/nats/it/NatsTestResource.java        |   6 +-
 integration-tests/solr/pom.xml                     |  96 +++---
 .../src/main/resources/application.properties      |  10 +-
 .../camel/quarkus/component/solr/it/SolrTest.java  |   2 +-
 .../solr/src/test/resources/ssl/README.adoc        |   6 +
 .../solr/src/test/resources/ssl/solr-ssl.der       |  22 ++
 .../src/test/resources/ssl/solr-ssl.keystore.p12   | Bin 2659 -> 0 bytes
 .../solr/src/test/resources/ssl/solr-ssl.pem       |  63 ----
 pom.xml                                            |   3 +-
 tooling/scripts/test-categories.yaml               |   2 +-
 32 files changed, 1055 insertions(+), 134 deletions(-)
 copy docs/modules/ROOT/partials/reference/{others/zipkin.adoc => components/vertx-kafka.adoc} (100%)
 create mode 100644 extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CSimpleRouteDefinitionProcessor.java
 create mode 100644 extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/LanguageExpressionContentHandler.java
 create mode 100644 extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CSimpleExpressionSourceBuildItem.java
 copy extensions/xslt/deployment/src/main/java/org/apache/camel/quarkus/component/xslt/deployment/XsltGeneratedClassBuildItem.java => extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java (51%)
 create mode 100644 extensions-core/core/runtime/src/main/adoc/limitations.adoc
 copy extensions-jvm/management/runtime/src/main/java/org/apache/camel/quarkus/component/management/CamelManagementRecorder.java => extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CSimpleLanguageRecorder.java (56%)
 create mode 100644 extensions-core/main/deployment/src/main/java/org/apache/camel/quarkus/main/deployment/CSimpleXmlProcessor.java
 create mode 100644 integration-tests-support/test-support/src/main/java/org/apache/camel/quarkus/test/ExtendDefaultTrustStore.java
 copy integration-tests/{bean => solr}/src/main/resources/application.properties (75%)
 create mode 100644 integration-tests/solr/src/test/resources/ssl/README.adoc
 create mode 100644 integration-tests/solr/src/test/resources/ssl/solr-ssl.der
 delete mode 100644 integration-tests/solr/src/test/resources/ssl/solr-ssl.keystore.p12
 delete mode 100644 integration-tests/solr/src/test/resources/ssl/solr-ssl.pem


[camel-quarkus] 05/06: Remove Camel AS2 configuration class reflection registration

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

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

commit ac39f0386cc327df7e2aec2ce05972a1866fdb83
Author: James Netherton <ja...@gmail.com>
AuthorDate: Mon Dec 7 07:36:51 2020 +0000

    Remove Camel AS2 configuration class reflection registration
    
    Fixes #1874
---
 .../apache/camel/quarkus/component/as2/deployment/As2Processor.java   | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/extensions/as2/deployment/src/main/java/org/apache/camel/quarkus/component/as2/deployment/As2Processor.java b/extensions/as2/deployment/src/main/java/org/apache/camel/quarkus/component/as2/deployment/As2Processor.java
index 8aebdaf..e4e21b7 100644
--- a/extensions/as2/deployment/src/main/java/org/apache/camel/quarkus/component/as2/deployment/As2Processor.java
+++ b/extensions/as2/deployment/src/main/java/org/apache/camel/quarkus/component/as2/deployment/As2Processor.java
@@ -26,8 +26,6 @@ import io.quarkus.deployment.builditem.LogConsoleFormatBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
-import org.apache.camel.component.as2.AS2ClientManagerEndpointConfiguration;
-import org.apache.camel.component.as2.AS2ServerManagerEndpointConfiguration;
 import org.apache.camel.component.as2.api.util.AS2Utils;
 import org.apache.camel.quarkus.component.as2.As2Recorder;
 import org.jboss.jandex.IndexView;
@@ -49,8 +47,6 @@ class As2Processor {
     @BuildStep
     ReflectiveClassBuildItem registerAs2ConfigurationForReflection() {
         return new ReflectiveClassBuildItem(true, true,
-                AS2ServerManagerEndpointConfiguration.class.getCanonicalName(),
-                AS2ClientManagerEndpointConfiguration.class.getCanonicalName(),
                 java.security.AlgorithmParameterGeneratorSpi.class.getCanonicalName());
     }
 


[camel-quarkus] 03/06: Google PubSub native support

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

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

commit aef9ea80ecad1443352ccc011fb274207b129052
Author: James Netherton <ja...@gmail.com>
AuthorDate: Wed Dec 2 10:41:18 2020 +0000

    Google PubSub native support
    
    Fixes #1041
---
 .../pages/reference/extensions/google-pubsub.adoc  |  18 ++-
 .../reference/components/google-pubsub.adoc        |   6 +-
 .../google-pubsub/integration-test/pom.xml         |  66 ---------
 .../google/pubsub/it/GooglePubsubResource.java     |  51 -------
 extensions-jvm/pom.xml                             |   1 -
 .../google-pubsub/deployment/pom.xml               |   8 +
 .../pubsub/deployment/GooglePubsubProcessor.java   |  32 ++--
 .../google-pubsub/pom.xml                          |   1 -
 .../google-pubsub/runtime/pom.xml                  |  21 ++-
 .../runtime/src/main/doc/limitations.adoc          |   6 +
 .../google/pubsub/GooglePubsubRecorder.java        |  41 ++++++
 .../pubsub/JacksonGooglePubsubSerializer.java      |  29 ++--
 .../main/resources/META-INF/quarkus-extension.yaml |   3 +-
 extensions/pom.xml                                 |   1 +
 integration-tests/google-pubsub/pom.xml            | 122 ++++++++++++++++
 .../quarkus/component/google/pubsub/it/Fruit.java  |  22 +--
 .../google/pubsub/it/GooglePubsubResource.java     |  70 +++++++++
 .../component/google/pubsub/it/GooglePubsubIT.java |  15 +-
 .../google/pubsub/it/GooglePubsubTest.java         |  34 ++++-
 .../google/pubsub/it/GooglePubsubTestResource.java | 161 +++++++++++++++++++++
 integration-tests/pom.xml                          |   1 +
 pom.xml                                            |   6 +-
 poms/bom/pom.xml                                   |  28 ++--
 tooling/scripts/test-categories.yaml               |   1 +
 24 files changed, 554 insertions(+), 190 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/google-pubsub.adoc b/docs/modules/ROOT/pages/reference/extensions/google-pubsub.adoc
index d2f1acc..cf1d22b 100644
--- a/docs/modules/ROOT/pages/reference/extensions/google-pubsub.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/google-pubsub.adoc
@@ -3,15 +3,15 @@
 = Google Pubsub
 :page-aliases: extensions/google-pubsub.adoc
 :cq-artifact-id: camel-quarkus-google-pubsub
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-description: Send and receive messages to/from Google Cloud Platform PubSub Service.
 :cq-deprecated: false
 :cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
+:cq-native-since: 1.5.0
 
 [.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.0.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.0.0## [.badge-key]##Native since##[.badge-supported]##1.5.0##
 
 Send and receive messages to/from Google Cloud Platform PubSub Service.
 
@@ -32,3 +32,13 @@ Please refer to the above link for usage and configuration details.
 ----
 
 Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+
+== Camel Quarkus limitations
+
+By default, the Camel PubSub component uses JDK object serialization via `ObjectOutputStream` whenever the message body is anything other than `String` or `byte[]`.
+
+Since such serialization is not yet supported by GraalVM, this extension provides a custom Jackson based serializer to serialize complex message payloads as JSON.
+
+If your payload contains binary data, then you will need to handle that by creating a custom Jackson Serializer / Deserializer. Refer to the https://quarkus.io/guides/writing-extensions#customizing-jackson[Quarkus Jackson guide] for 
+information on how to do this.
+
diff --git a/docs/modules/ROOT/partials/reference/components/google-pubsub.adoc b/docs/modules/ROOT/partials/reference/components/google-pubsub.adoc
index 4a45c2c..8725241 100644
--- a/docs/modules/ROOT/partials/reference/components/google-pubsub.adoc
+++ b/docs/modules/ROOT/partials/reference/components/google-pubsub.adoc
@@ -2,11 +2,11 @@
 // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
 :cq-artifact-id: camel-quarkus-google-pubsub
 :cq-artifact-id-base: google-pubsub
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-deprecated: false
 :cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
+:cq-native-since: 1.5.0
 :cq-camel-part-name: google-pubsub
 :cq-camel-part-title: Google Pubsub
 :cq-camel-part-description: Send and receive messages to/from Google Cloud Platform PubSub Service.
diff --git a/extensions-jvm/google-pubsub/integration-test/pom.xml b/extensions-jvm/google-pubsub/integration-test/pom.xml
deleted file mode 100644
index af13b7c..0000000
--- a/extensions-jvm/google-pubsub/integration-test/pom.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?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-build-parent-it</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
-        <relativePath>../../../poms/build-parent-it/pom.xml</relativePath>
-    </parent>
-
-    <artifactId>camel-quarkus-google-pubsub-integration-test</artifactId>
-    <name>Camel Quarkus :: Google Pubsub :: Integration Test</name>
-    <description>Integration tests for Camel Quarkus Google Pubsub extension</description>
-
-    <properties>
-        <!-- mvnd, a.k.a. Maven Daemon: https://github.com/mvndaemon/mvnd -->
-        <!-- The following rule tells mvnd to build the listed deployment modules before this module. -->
-        <!-- This is important because mvnd builds modules in parallel by default. The deployment modules are not -->
-        <!-- explicit dependencies of this module in the Maven sense, although they are required by the Quarkus Maven plugin. -->
-        <!-- Please update the rule whenever you change the dependencies of this module by running -->
-        <!--     mvn process-resources -Pformat    from the root directory -->
-        <mvnd.builder.rule>camel-quarkus-google-pubsub-deployment</mvnd.builder.rule>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-google-pubsub</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>
-
-</project>
diff --git a/extensions-jvm/google-pubsub/integration-test/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java b/extensions-jvm/google-pubsub/integration-test/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java
deleted file mode 100644
index 39aa2f3..0000000
--- a/extensions-jvm/google-pubsub/integration-test/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.quarkus.component.google.pubsub.it;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-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.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/google-pubsub")
-@ApplicationScoped
-public class GooglePubsubResource {
-
-    private static final Logger LOG = Logger.getLogger(GooglePubsubResource.class);
-
-    private static final String COMPONENT_GOOGLE_PUBSUB = "google-pubsub";
-    @Inject
-    CamelContext context;
-
-    @Path("/load/component/google-pubsub")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentGooglePubsub() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_GOOGLE_PUBSUB) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_GOOGLE_PUBSUB);
-        return Response.status(500, COMPONENT_GOOGLE_PUBSUB + " could not be loaded from the Camel context").build();
-    }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 4eef5cb..24750af 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -72,7 +72,6 @@
         <module>freemarker</module>
         <module>ganglia</module>
         <module>google-bigquery</module>
-        <module>google-pubsub</module>
         <module>groovy</module>
         <module>guava-eventbus</module>
         <module>hazelcast</module>
diff --git a/extensions-jvm/google-pubsub/deployment/pom.xml b/extensions/google-pubsub/deployment/pom.xml
similarity index 88%
rename from extensions-jvm/google-pubsub/deployment/pom.xml
rename to extensions/google-pubsub/deployment/pom.xml
index 4be7c3b..023d43b 100644
--- a/extensions-jvm/google-pubsub/deployment/pom.xml
+++ b/extensions/google-pubsub/deployment/pom.xml
@@ -31,6 +31,14 @@
 
     <dependencies>
         <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jackson-deployment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkiverse.googlecloudservices</groupId>
+            <artifactId>quarkus-google-cloud-pubsub-deployment</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
diff --git a/extensions-jvm/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java b/extensions/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java
similarity index 51%
rename from extensions-jvm/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java
rename to extensions/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java
index 40fea4d..2377149 100644
--- a/extensions-jvm/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java
+++ b/extensions/google-pubsub/deployment/src/main/java/org/apache/camel/quarkus/component/google/pubsub/deployment/GooglePubsubProcessor.java
@@ -16,17 +16,20 @@
  */
 package org.apache.camel.quarkus.component.google.pubsub.deployment;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
+import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.annotations.ExecutionTime;
 import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
+import io.quarkus.jackson.ObjectMapperProducer;
+import org.apache.camel.component.google.pubsub.serializer.GooglePubsubSerializer;
+import org.apache.camel.quarkus.component.google.pubsub.GooglePubsubRecorder;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBeanBuildItem;
 
 class GooglePubsubProcessor {
 
-    private static final Logger LOG = Logger.getLogger(GooglePubsubProcessor.class);
     private static final String FEATURE = "camel-google-pubsub";
 
     @BuildStep
@@ -34,13 +37,18 @@ class GooglePubsubProcessor {
         return new FeatureBuildItem(FEATURE);
     }
 
-    /**
-     * Remove this once this extension starts supporting the native mode.
-     */
-    @BuildStep(onlyIf = NativeBuild.class)
-    @Record(value = ExecutionTime.RUNTIME_INIT)
-    void warnJvmInNative(JvmOnlyRecorder recorder) {
-        JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
-        recorder.warnJvmInNative(FEATURE); // warn at runtime
+    @BuildStep
+    public void markObjectMapperUnremovable(BuildProducer<UnremovableBeanBuildItem> unremovable) {
+        unremovable.produce(new UnremovableBeanBuildItem(
+                new UnremovableBeanBuildItem.BeanClassNameExclusion(ObjectMapper.class.getName())));
+        unremovable.produce(new UnremovableBeanBuildItem(
+                new UnremovableBeanBuildItem.BeanClassNameExclusion(ObjectMapperProducer.class.getName())));
+    }
+
+    @BuildStep
+    @Record(ExecutionTime.RUNTIME_INIT)
+    public CamelRuntimeBeanBuildItem createGooglePubsubSerializerBean(GooglePubsubRecorder recorder) {
+        return new CamelRuntimeBeanBuildItem("googlePubsubSerializer", GooglePubsubSerializer.class.getTypeName(),
+                recorder.createSerializer());
     }
 }
diff --git a/extensions-jvm/google-pubsub/pom.xml b/extensions/google-pubsub/pom.xml
similarity index 97%
rename from extensions-jvm/google-pubsub/pom.xml
rename to extensions/google-pubsub/pom.xml
index 870c27f..d7dbb0b 100644
--- a/extensions-jvm/google-pubsub/pom.xml
+++ b/extensions/google-pubsub/pom.xml
@@ -33,6 +33,5 @@
     <modules>
         <module>deployment</module>
         <module>runtime</module>
-        <module>integration-test</module>
     </modules>
 </project>
diff --git a/extensions-jvm/google-pubsub/runtime/pom.xml b/extensions/google-pubsub/runtime/pom.xml
similarity index 82%
rename from extensions-jvm/google-pubsub/runtime/pom.xml
rename to extensions/google-pubsub/runtime/pom.xml
index 3ef7db4..26548f6 100644
--- a/extensions-jvm/google-pubsub/runtime/pom.xml
+++ b/extensions/google-pubsub/runtime/pom.xml
@@ -31,7 +31,7 @@
 
     <properties>
         <camel.quarkus.jvmSince>1.0.0</camel.quarkus.jvmSince>
-        <camel.quarkus.nativeSince>1.0.0</camel.quarkus.nativeSince>
+        <camel.quarkus.nativeSince>1.5.0</camel.quarkus.nativeSince>
     </properties>
 
     <dependencyManagement>
@@ -43,11 +43,30 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <!-- https://github.com/micrometer-metrics/micrometer/issues/2249 -->
+            <dependency>
+                <groupId>io.quarkus</groupId>
+                <artifactId>quarkus-micrometer</artifactId>
+                <exclusions>
+                    <exclusion>
+                        <groupId>com.google.cloud</groupId>
+                        <artifactId>google-cloud-monitoring</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
     <dependencies>
         <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jackson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkiverse.googlecloudservices</groupId>
+            <artifactId>quarkus-google-cloud-pubsub</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
diff --git a/extensions/google-pubsub/runtime/src/main/doc/limitations.adoc b/extensions/google-pubsub/runtime/src/main/doc/limitations.adoc
new file mode 100644
index 0000000..49606e0
--- /dev/null
+++ b/extensions/google-pubsub/runtime/src/main/doc/limitations.adoc
@@ -0,0 +1,6 @@
+By default, the Camel PubSub component uses JDK object serialization via `ObjectOutputStream` whenever the message body is anything other than `String` or `byte[]`.
+
+Since such serialization is not yet supported by GraalVM, this extension provides a custom Jackson based serializer to serialize complex message payloads as JSON.
+
+If your payload contains binary data, then you will need to handle that by creating a custom Jackson Serializer / Deserializer. Refer to the https://quarkus.io/guides/writing-extensions#customizing-jackson[Quarkus Jackson guide] for 
+information on how to do this.
diff --git a/extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/GooglePubsubRecorder.java b/extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/GooglePubsubRecorder.java
new file mode 100644
index 0000000..a9dd14e
--- /dev/null
+++ b/extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/GooglePubsubRecorder.java
@@ -0,0 +1,41 @@
+/*
+ * 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.quarkus.component.google.pubsub;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.quarkus.arc.Arc;
+import io.quarkus.arc.InstanceHandle;
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.component.google.pubsub.serializer.GooglePubsubSerializer;
+
+@Recorder
+public class GooglePubsubRecorder {
+
+    public RuntimeValue<GooglePubsubSerializer> createSerializer() {
+        GooglePubsubSerializer serializer = new JacksonGooglePubsubSerializer(getObjectMapper());
+        return new RuntimeValue<>(serializer);
+    }
+
+    private ObjectMapper getObjectMapper() {
+        InstanceHandle<ObjectMapper> instance = Arc.container().instance(ObjectMapper.class);
+        if (instance.isAvailable()) {
+            return instance.get();
+        }
+        return new ObjectMapper();
+    }
+}
diff --git a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java b/extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/JacksonGooglePubsubSerializer.java
similarity index 50%
copy from extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
copy to extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/JacksonGooglePubsubSerializer.java
index 9987659..696267b 100644
--- a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
+++ b/extensions/google-pubsub/runtime/src/main/java/org/apache/camel/quarkus/component/google/pubsub/JacksonGooglePubsubSerializer.java
@@ -14,20 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.google.pubsub.it;
+package org.apache.camel.quarkus.component.google.pubsub;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import java.io.IOException;
 
-@QuarkusTest
-class GooglePubsubTest {
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.camel.component.google.pubsub.serializer.GooglePubsubSerializer;
 
-    @Test
-    public void loadComponentGooglePubsub() {
-        RestAssured.get("/google-pubsub/load/component/google-pubsub")
-                .then()
-                .statusCode(200);
+/**
+ * A Jackson implementation of {@link GooglePubsubSerializer} which serializes a given payload to JSON instead of
+ * the default implementation that uses (unsuitable for native mode) JDK object serialization.
+ */
+public class JacksonGooglePubsubSerializer implements GooglePubsubSerializer {
+
+    private final ObjectMapper mapper;
+
+    public JacksonGooglePubsubSerializer(ObjectMapper mapper) {
+        this.mapper = mapper;
     }
 
+    @Override
+    public byte[] serialize(Object payload) throws IOException {
+        return this.mapper.writeValueAsBytes(payload);
+    }
 }
diff --git a/extensions-jvm/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from extensions-jvm/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 715af95..9c721ea 100644
--- a/extensions-jvm/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/google-pubsub/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
 name: "Camel Google Pubsub"
 description: "Send and receive messages to/from Google Cloud Platform PubSub Service"
 metadata:
-  unlisted: true
   guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/google-pubsub.html"
   categories:
   - "integration"
   status:
-  - "preview"
+  - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index a29085f..9beeb7c 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -112,6 +112,7 @@
         <module>google-calendar</module>
         <module>google-drive</module>
         <module>google-mail</module>
+        <module>google-pubsub</module>
         <module>google-sheets</module>
         <module>graphql</module>
         <module>grok</module>
diff --git a/integration-tests/google-pubsub/pom.xml b/integration-tests/google-pubsub/pom.xml
new file mode 100644
index 0000000..64533e4
--- /dev/null
+++ b/integration-tests/google-pubsub/pom.xml
@@ -0,0 +1,122 @@
+<?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-integration-tests</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-quarkus-integration-test-google-pubsub</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: Google Pubsub</name>
+    <description>Integration tests for Camel Quarkus Google Pubsub extension</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-main</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-google-pubsub</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>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-integration-testcontainers-support</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-google-pubsub-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-main-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>native</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.package.type>native</quarkus.package.type>
+            </properties>
+            <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>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java b/integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/Fruit.java
similarity index 72%
copy from extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
copy to integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/Fruit.java
index 9987659..1de6e4e 100644
--- a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
+++ b/integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/Fruit.java
@@ -16,18 +16,20 @@
  */
 package org.apache.camel.quarkus.component.google.pubsub.it;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.quarkus.runtime.annotations.RegisterForReflection;
 
-@QuarkusTest
-class GooglePubsubTest {
+@RegisterForReflection
+public class Fruit {
 
-    @Test
-    public void loadComponentGooglePubsub() {
-        RestAssured.get("/google-pubsub/load/component/google-pubsub")
-                .then()
-                .statusCode(200);
+    @JsonProperty
+    private String name;
+
+    public Fruit(String name) {
+        this.name = name;
     }
 
+    public String getName() {
+        return name;
+    }
 }
diff --git a/integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java b/integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java
new file mode 100644
index 0000000..86fe059
--- /dev/null
+++ b/integration-tests/google-pubsub/src/main/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubResource.java
@@ -0,0 +1,70 @@
+/*
+ * 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.quarkus.component.google.pubsub.it;
+
+import java.net.URI;
+
+import javax.inject.Inject;
+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;
+
+@Path("/google-pubsub")
+public class GooglePubsubResource {
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Inject
+    ConsumerTemplate consumerTemplate;
+
+    @POST
+    public Response sendStringToTopic(String message) {
+        producerTemplate.sendBody("google-pubsub:{{project.id}}:{{topic.name}}", message);
+        return Response.created(URI.create("https://camel.apache.org")).build();
+    }
+
+    @GET
+    public Response consumeStringFromTopic() {
+        Object response = consumerTemplate
+                .receiveBody("google-pubsub:{{project.id}}:{{subscription.name}}?synchronousPull=true", 5000L);
+        return Response.ok(response).build();
+    }
+
+    @Path("/pojo")
+    @POST
+    public Response sendPojoToTopic(String fruitName) {
+        Fruit fruit = new Fruit(fruitName);
+        producerTemplate.sendBody("google-pubsub:{{project.id}}:{{topic.name}}", fruit);
+        return Response.created(URI.create("https://camel.apache.org")).build();
+    }
+
+    @Path("/pojo")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response consumePojoFromTopic() {
+        Object response = consumerTemplate
+                .receiveBody("google-pubsub:{{project.id}}:{{subscription.name}}?synchronousPull=true", 5000L);
+        return Response.ok(response).build();
+    }
+}
diff --git a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubIT.java
similarity index 71%
copy from extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
copy to integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubIT.java
index 9987659..d8aac91 100644
--- a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
+++ b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubIT.java
@@ -16,18 +16,9 @@
  */
 package org.apache.camel.quarkus.component.google.pubsub.it;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import io.quarkus.test.junit.NativeImageTest;
 
-@QuarkusTest
-class GooglePubsubTest {
-
-    @Test
-    public void loadComponentGooglePubsub() {
-        RestAssured.get("/google-pubsub/load/component/google-pubsub")
-                .then()
-                .statusCode(200);
-    }
+@NativeImageTest
+class GooglePubsubIT extends GooglePubsubTest {
 
 }
diff --git a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
similarity index 53%
rename from extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
rename to integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
index 9987659..0073390 100644
--- a/extensions-jvm/google-pubsub/integration-test/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
+++ b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTest.java
@@ -16,18 +16,46 @@
  */
 package org.apache.camel.quarkus.component.google.pubsub.it;
 
+import io.quarkus.test.common.QuarkusTestResource;
 import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
 import org.junit.jupiter.api.Test;
 
+import static org.hamcrest.CoreMatchers.is;
+
 @QuarkusTest
+@QuarkusTestResource(GooglePubsubTestResource.class)
 class GooglePubsubTest {
 
     @Test
-    public void loadComponentGooglePubsub() {
-        RestAssured.get("/google-pubsub/load/component/google-pubsub")
+    public void pubsubTopicProduceConsume() {
+        String message = "Hello Camel Quarkus Google PubSub";
+
+        RestAssured.given()
+                .body(message)
+                .post("/google-pubsub")
                 .then()
-                .statusCode(200);
+                .statusCode(201);
+
+        RestAssured.get("/google-pubsub")
+                .then()
+                .statusCode(200)
+                .body(is(message));
     }
 
+    @Test
+    public void jacksonSerializer() {
+        String fruitName = "Apple";
+
+        RestAssured.given()
+                .body(fruitName)
+                .post("/google-pubsub/pojo")
+                .then()
+                .statusCode(201);
+
+        RestAssured.get("/google-pubsub/pojo")
+                .then()
+                .statusCode(200)
+                .body("name", is(fruitName));
+    }
 }
diff --git a/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTestResource.java b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTestResource.java
new file mode 100644
index 0000000..4e27bd5
--- /dev/null
+++ b/integration-tests/google-pubsub/src/test/java/org/apache/camel/quarkus/component/google/pubsub/it/GooglePubsubTestResource.java
@@ -0,0 +1,161 @@
+/*
+ * 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.quarkus.component.google.pubsub.it;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.google.api.gax.core.CredentialsProvider;
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.GrpcTransportChannel;
+import com.google.api.gax.rpc.FixedTransportChannelProvider;
+import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
+import com.google.cloud.pubsub.v1.SubscriptionAdminSettings;
+import com.google.cloud.pubsub.v1.TopicAdminClient;
+import com.google.cloud.pubsub.v1.TopicAdminSettings;
+import com.google.pubsub.v1.ProjectSubscriptionName;
+import com.google.pubsub.v1.Subscription;
+import com.google.pubsub.v1.Topic;
+import com.google.pubsub.v1.TopicName;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.apache.camel.util.CollectionHelper;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+
+public class GooglePubsubTestResource implements QuarkusTestResourceLifecycleManager {
+
+    private static final String PROJECT_ID = "test-project";
+    private static final String TOPIC = "test-topic";
+    private static final String SUBSCRIPTION = TOPIC + "-subscription";
+    private static final String GOOGLE_PUBSUB_IMAGE = "google/cloud-sdk:latest";
+    private static final int GOOGLE_PUBSUB_PORT = 8383;
+
+    private GenericContainer<?> container;
+
+    @Override
+    public Map<String, String> start() {
+        try {
+            container = new GenericContainer<>(GOOGLE_PUBSUB_IMAGE)
+                    .withCommand("/bin/sh", "-c",
+                            String.format("gcloud beta emulators pubsub start --project %s --host-port=0.0.0.0:%d",
+                                    PROJECT_ID, GOOGLE_PUBSUB_PORT))
+                    .withExposedPorts(GOOGLE_PUBSUB_PORT)
+                    .waitingFor(new LogMessageWaitStrategy().withRegEx("(?s).*started.*$"));
+
+            container.start();
+
+            createTopicSubscriptionPair(TOPIC, SUBSCRIPTION);
+
+            String endpointAddress = String.format("%s:%s", container.getContainerIpAddress(), container.getFirstMappedPort());
+
+            return CollectionHelper.mapOf(
+                    "project.id", PROJECT_ID,
+                    "topic.name", TOPIC,
+                    "subscription.name", SUBSCRIPTION,
+                    "camel.component.google-pubsub.endpoint", endpointAddress);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void stop() {
+        try {
+            if (container != null) {
+                container.stop();
+            }
+        } catch (Exception e) {
+            // ignored
+        }
+    }
+
+    public void createTopicSubscriptionPair(String topicName, String subscriptionName) throws InterruptedException {
+        TopicName projectTopicName = TopicName.of(PROJECT_ID, topicName);
+        ProjectSubscriptionName projectSubscriptionName = ProjectSubscriptionName.of(PROJECT_ID, subscriptionName);
+
+        Topic topic = Topic.newBuilder().setName(projectTopicName.toString()).build();
+        Subscription subscription = Subscription.newBuilder()
+                .setName(projectSubscriptionName.toString())
+                .setTopic(topic.getName())
+                .setAckDeadlineSeconds(10)
+                .build();
+
+        createTopicSubscriptionPair(topic, subscription);
+    }
+
+    public void createTopicSubscriptionPair(Topic topic, Subscription subscription) throws InterruptedException {
+        createTopic(topic);
+        createSubscription(subscription);
+    }
+
+    public void createTopic(Topic topic) throws InterruptedException {
+        TopicAdminClient topicAdminClient = createTopicAdminClient();
+        topicAdminClient.createTopic(topic);
+        topicAdminClient.shutdown();
+        topicAdminClient.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    public void createSubscription(Subscription subscription) throws InterruptedException {
+        SubscriptionAdminClient subscriptionAdminClient = createSubscriptionAdminClient();
+        subscriptionAdminClient.createSubscription(subscription);
+        subscriptionAdminClient.shutdown();
+        subscriptionAdminClient.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    private FixedTransportChannelProvider createChannelProvider() {
+        Integer port = container.getFirstMappedPort();
+        ManagedChannel channel = ManagedChannelBuilder
+                .forTarget(String.format("%s:%s", "localhost", port))
+                .usePlaintext()
+                .build();
+
+        return FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
+    }
+
+    private TopicAdminClient createTopicAdminClient() {
+        FixedTransportChannelProvider channelProvider = createChannelProvider();
+        CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
+
+        try {
+            return TopicAdminClient.create(
+                    TopicAdminSettings.newBuilder()
+                            .setTransportChannelProvider(channelProvider)
+                            .setCredentialsProvider(credentialsProvider)
+                            .build());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private SubscriptionAdminClient createSubscriptionAdminClient() {
+        FixedTransportChannelProvider channelProvider = createChannelProvider();
+        CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
+
+        try {
+            return SubscriptionAdminClient.create(
+                    SubscriptionAdminSettings.newBuilder()
+                            .setTransportChannelProvider(channelProvider)
+                            .setCredentialsProvider(credentialsProvider)
+                            .build());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 1326867..a37f22f 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -99,6 +99,7 @@
         <module>git</module>
         <module>github</module>
         <module>google</module>
+        <module>google-pubsub</module>
         <module>graphql</module>
         <module>grok</module>
         <module>grpc</module>
diff --git a/pom.xml b/pom.xml
index 1e0c8cc..a9209ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
         <jodatime.version>2.10.6</jodatime.version><!-- Mess in transitive dependencies of Spark and Splunk -->
         <github-api.version>1.111</github-api.version>
         <google-http-client.version>1.34.0</google-http-client.version>
-        <google-api-common.version>1.9.0</google-api-common.version><!-- Mess in pubsub transitive deps vs google cloud deps -->
+        <google-auth-library-oauth2-http.version>0.21.1</google-auth-library-oauth2-http.version> <!-- Mess in google-cloud-bom -->
         <guava.version>29.0-jre</guava.version>
         <gson.version>2.8.5</gson.version>
         <hadoop2.version>${hadoop2-version}</hadoop2.version><!-- Spark -->
@@ -84,9 +84,9 @@
         <nimbus-jose-jwt.version>4.41.1</nimbus-jose-jwt.version><!-- Mess in hdfs transitive deps -->
         <okhttp.version>${squareup-okhttp-version}</okhttp.version><!-- keep in sync with okio -->
         <okio.version>${squareup-okio-version}</okio.version><!-- keep in sync with okhttp -->
-        <opencensus-api.version>0.26.0</opencensus-api.version><!-- Mess in pubsub transitive deps vs google cloud deps -->
         <optaplanner.version>7.46.0.Final</optaplanner.version>
         <quarkus.version>1.10.3.Final</quarkus.version>
+        <quarkus-google-cloud.version>0.2.0</quarkus-google-cloud.version>
         <quarkus-qpid-jms.version>0.21.0</quarkus-qpid-jms.version>
         <protobuf.version>${protobuf-version}</protobuf.version>
         <retrofit.version>2.5.0</retrofit.version>
@@ -128,8 +128,6 @@
         <exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
         <formatter-maven-plugin.version>2.11.0</formatter-maven-plugin.version>
         <frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>
-        <google-auth-library-credentials.version>0.19.0</google-auth-library-credentials.version>
-        <google-auth-library-oauth2-http.version>0.19.0</google-auth-library-oauth2-http.version>
         <groovy-maven-plugin.version>2.1.1</groovy-maven-plugin.version>
         <groovy.version>3.0.5</groovy.version>
         <impsort-maven-plugin.version>1.3.2</impsort-maven-plugin.version>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index ac6aef3..3f93063 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -906,6 +906,16 @@
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-google-pubsub</artifactId>
                 <version>${camel.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>com.google.cloud</groupId>
+                        <artifactId>google-cloud-pubsub</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.google.guava</groupId>
+                        <artifactId>guava</artifactId>
+                    </exclusion>
+                </exclusions>
             </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
@@ -5366,11 +5376,6 @@
                 </exclusions>
             </dependency>
             <dependency>
-                <groupId>com.google.api</groupId>
-                <artifactId>api-common</artifactId>
-                <version>${google-api-common.version}</version>
-            </dependency>
-            <dependency>
                 <groupId>com.google.api.grpc</groupId>
                 <artifactId>proto-google-common-protos</artifactId>
                 <version>${proto-google-common-protos.version}</version>
@@ -5378,7 +5383,7 @@
             <dependency>
                 <groupId>com.google.auth</groupId>
                 <artifactId>google-auth-library-credentials</artifactId>
-                <version>${google-auth-library-credentials.version}</version>
+                <version>${google-auth-library-oauth2-http.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.google.auth</groupId>
@@ -5523,9 +5528,14 @@
                 <version>${debezium.version}</version>
             </dependency>
             <dependency>
-                <groupId>io.opencensus</groupId>
-                <artifactId>opencensus-api</artifactId>
-                <version>${opencensus-api.version}</version>
+                <groupId>io.quarkiverse.googlecloudservices</groupId>
+                <artifactId>quarkus-google-cloud-pubsub</artifactId>
+                <version>${quarkus-google-cloud.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.quarkiverse.googlecloudservices</groupId>
+                <artifactId>quarkus-google-cloud-pubsub-deployment</artifactId>
+                <version>${quarkus-google-cloud.version}</version>
             </dependency>
             <dependency>
                 <groupId>io.smallrye.reactive</groupId>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index 40c90ae..c3bcf73 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -31,6 +31,7 @@ cloud:
   - azure
   - consul
   - elasticsearch-rest
+  - google-pubsub
   - grpc
   - protobuf
   - smallrye-reactive-messaging


[camel-quarkus] 02/06: [Camel 3.7] JSON-B data format support

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

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

commit bfd1833ad5d13b5f940bb97ab7d6c2f9c95060d9
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Thu Nov 5 13:02:17 2020 +0100

    [Camel 3.7] JSON-B data format support
---
 catalog/pom.xml                                    |  13 ++
 .../ROOT/pages/reference/extensions/jsonb.adoc     |  38 +++++
 .../partials/reference/dataformats/json-jsonb.adoc |  14 +-
 extensions/jsonb/deployment/pom.xml                |  67 +++++++++
 .../component/jsonb/deployment/JsonbProcessor.java |  31 +++++
 extensions/jsonb/pom.xml                           |  39 ++++++
 extensions/jsonb/runtime/pom.xml                   | 105 ++++++++++++++
 .../jsonb/runtime/src/main/doc/configuration.adoc  |   1 +
 .../main/resources/META-INF/quarkus-extension.yaml |  31 +++++
 extensions/pom.xml                                 |   1 +
 integration-tests/jsonb/pom.xml                    | 154 +++++++++++++++++++++
 .../quarkus/component/jsonb/it/JsonbResource.java  |  81 +++++++++++
 .../component/jsonb/it/JsonbRouteBuilder.java      |  38 +++++
 .../camel/quarkus/component/jsonb/it/TestPojo.java |  48 +++++++
 .../camel/quarkus/component/jsonb/it/JsonbIT.java  |  24 ++++
 .../quarkus/component/jsonb/it/JsonbTest.java      | 119 ++++++++++++++++
 integration-tests/pom.xml                          |   1 +
 poms/bom/pom.xml                                   |  15 ++
 tooling/scripts/test-categories.yaml               |   1 +
 19 files changed, 820 insertions(+), 1 deletion(-)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 09745bb..19e46f5 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -2207,6 +2207,19 @@
         </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsonb</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-jsonpath</artifactId>
             <version>${project.version}</version>
             <type>pom</type>
diff --git a/docs/modules/ROOT/pages/reference/extensions/jsonb.adoc b/docs/modules/ROOT/pages/reference/extensions/jsonb.adoc
new file mode 100644
index 0000000..47ea4b2
--- /dev/null
+++ b/docs/modules/ROOT/pages/reference/extensions/jsonb.adoc
@@ -0,0 +1,38 @@
+// Do not edit directly!
+// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+= JSON JSON-B
+:cq-artifact-id: camel-quarkus-jsonb
+:cq-native-supported: true
+:cq-status: Stable
+:cq-description: Marshal POJOs to JSON and back using JSON-B.
+:cq-deprecated: false
+:cq-jvm-since: 1.5.0
+:cq-native-since: 1.5.0
+
+[.badges]
+[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native since##[.badge-supported]##1.5.0##
+
+Marshal POJOs to JSON and back using JSON-B.
+
+== What's inside
+
+* xref:latest@components:dataformats:json-jsonb-dataformat.adoc[JSON JSON-B data format]
+
+Please refer to the above link for usage and configuration details.
+
+== Maven coordinates
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel.quarkus</groupId>
+    <artifactId>camel-quarkus-jsonb</artifactId>
+</dependency>
+----
+
+Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+
+== Additional Camel Quarkus configuration
+
+Extension contains `io.quarkus:quarkus-jsonb` dependency. No jsonb implementation has to be provided.
+
diff --git a/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc b/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc
index a509c1d..f5f90c8 100644
--- a/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc
+++ b/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc
@@ -1 +1,13 @@
-// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
+// Do not edit directly!
+// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+:cq-artifact-id: camel-quarkus-jsonb
+:cq-artifact-id-base: jsonb
+:cq-native-supported: true
+:cq-status: Stable
+:cq-deprecated: false
+:cq-jvm-since: 1.5.0
+:cq-native-since: 1.5.0
+:cq-camel-part-name: json-jsonb
+:cq-camel-part-title: JSON JSON-B
+:cq-camel-part-description: Marshal POJOs to JSON and back using JSON-B.
+:cq-extension-page-title: JSON JSON-B
diff --git a/extensions/jsonb/deployment/pom.xml b/extensions/jsonb/deployment/pom.xml
new file mode 100644
index 0000000..541c242
--- /dev/null
+++ b/extensions/jsonb/deployment/pom.xml
@@ -0,0 +1,67 @@
+<?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-jsonb-parent</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-jsonb-deployment</artifactId>
+    <name>Camel Quarkus :: JSON JSON-B :: Deployment</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-core-deployment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsonb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jsonb-deployment</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>io.quarkus</groupId>
+                            <artifactId>quarkus-extension-processor</artifactId>
+                            <version>${quarkus.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/extensions/jsonb/deployment/src/main/java/org/apache/camel/quarkus/component/jsonb/deployment/JsonbProcessor.java b/extensions/jsonb/deployment/src/main/java/org/apache/camel/quarkus/component/jsonb/deployment/JsonbProcessor.java
new file mode 100644
index 0000000..54bff2b
--- /dev/null
+++ b/extensions/jsonb/deployment/src/main/java/org/apache/camel/quarkus/component/jsonb/deployment/JsonbProcessor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.quarkus.component.jsonb.deployment;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+
+class JsonbProcessor {
+
+    private static final String FEATURE = "camel-jsonb";
+
+    @BuildStep
+    FeatureBuildItem feature() {
+        return new FeatureBuildItem(FEATURE);
+    }
+
+}
diff --git a/extensions/jsonb/pom.xml b/extensions/jsonb/pom.xml
new file mode 100644
index 0000000..386557e
--- /dev/null
+++ b/extensions/jsonb/pom.xml
@@ -0,0 +1,39 @@
+<?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-build-parent</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath>../../poms/build-parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-jsonb-parent</artifactId>
+    <name>Camel Quarkus :: JSON JSON-B</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>deployment</module>
+        <module>runtime</module>
+    </modules>
+</project>
diff --git a/extensions/jsonb/runtime/pom.xml b/extensions/jsonb/runtime/pom.xml
new file mode 100644
index 0000000..f54cbfc
--- /dev/null
+++ b/extensions/jsonb/runtime/pom.xml
@@ -0,0 +1,105 @@
+<?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-jsonb-parent</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-jsonb</artifactId>
+    <name>Camel Quarkus :: JSON JSON-B :: Runtime</name>
+    <description>Marshal POJOs to JSON and back using JSON-B.</description>
+
+    <properties>
+        <camel.quarkus.jvmSince>1.5.0</camel.quarkus.jvmSince>
+        <camel.quarkus.nativeSince>1.5.0</camel.quarkus.nativeSince>
+    </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-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jsonb</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>*</artifactId>
+                    <groupId>org.apache.geronimo.specs</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jsonb</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>update-extension-doc-page</id>
+                        <goals><goal>update-extension-doc-page</goal></goals>
+                        <phase>process-classes</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>io.quarkus</groupId>
+                <artifactId>quarkus-bootstrap-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>io.quarkus</groupId>
+                            <artifactId>quarkus-extension-processor</artifactId>
+                            <version>${quarkus.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/extensions/jsonb/runtime/src/main/doc/configuration.adoc b/extensions/jsonb/runtime/src/main/doc/configuration.adoc
new file mode 100644
index 0000000..5487a90
--- /dev/null
+++ b/extensions/jsonb/runtime/src/main/doc/configuration.adoc
@@ -0,0 +1 @@
+Extension contains `io.quarkus:quarkus-jsonb` dependency. No jsonb implementation has to be provided.
\ No newline at end of file
diff --git a/extensions/jsonb/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/jsonb/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000..8b3e41a
--- /dev/null
+++ b/extensions/jsonb/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# This is a generated file. Do not edit directly!
+# To re-generate, run the following command from the top level directory:
+#
+#   mvn -N cq:update-quarkus-metadata
+#
+---
+name: "Camel JSON JSON-B"
+description: "Marshal POJOs to JSON and back using JSON-B"
+metadata:
+  guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/jsonb.html"
+  categories:
+  - "integration"
+  status:
+  - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index c853c44..a29085f 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -136,6 +136,7 @@
         <module>jsch</module>
         <module>jslt</module>
         <module>json-validator</module>
+        <module>jsonb</module>
         <module>jsonpath</module>
         <module>jta</module>
         <module>kafka</module>
diff --git a/integration-tests/jsonb/pom.xml b/integration-tests/jsonb/pom.xml
new file mode 100644
index 0000000..1623b03
--- /dev/null
+++ b/integration-tests/jsonb/pom.xml
@@ -0,0 +1,154 @@
+<?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-integration-tests</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-integration-test-jsonb</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: JSON JSON-B</name>
+    <description>Integration tests for Camel Quarkus JSON JSON-B extension</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-bom-test</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-jsonb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-jackson</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>
+
+        <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsonb-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </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</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.package.type>native</quarkus.package.type>
+            </properties>
+            <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>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbResource.java b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbResource.java
new file mode 100644
index 0000000..393f51c
--- /dev/null
+++ b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbResource.java
@@ -0,0 +1,81 @@
+/*
+ * 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.quarkus.component.jsonb.it;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+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.ProducerTemplate;
+import org.jboss.logging.Logger;
+
+@Path("/jsonb")
+@ApplicationScoped
+public class JsonbResource {
+
+    private static final Logger LOG = Logger.getLogger(JsonbResource.class);
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Path("/marshallMap")
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String marshallMap(Map map) {
+        return producerTemplate.requestBody("direct:marshallMap", map, String.class);
+    }
+
+    @Path("/unmarshallMap")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Map marshall(String message) throws Exception {
+        return producerTemplate.requestBody("direct:unmarshallMap", message, Map.class);
+    }
+
+    @Path("/marshallPojo")
+    @POST
+    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String marshallPojo(byte[] message) throws Exception {
+        TestPojo tp = new TestPojo();
+        tp.setName(message);
+        return producerTemplate.requestBody("direct:marshallPojo", tp, String.class);
+    }
+
+    @Path("/unmarshallPojo")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    public Response marshallPojo(String message) throws Exception {
+        TestPojo tp = producerTemplate.requestBody("direct:unmarshallPojo", message, TestPojo.class);
+        return Response
+                .created(new URI("https://camel.apache.org/"))
+                .entity(tp.getName())
+                .build();
+
+    }
+}
diff --git a/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbRouteBuilder.java b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbRouteBuilder.java
new file mode 100644
index 0000000..c365b41
--- /dev/null
+++ b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/JsonbRouteBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.quarkus.component.jsonb.it;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jsonb.JsonbDataFormat;
+
+public class JsonbRouteBuilder extends RouteBuilder {
+
+    @Override
+    public void configure() {
+
+        JsonbDataFormat format = new JsonbDataFormat();
+
+        from("direct:marshallMap").marshal(format);
+        from("direct:unmarshallMap").unmarshal(format);
+
+        JsonbDataFormat formatPojo = new JsonbDataFormat(TestPojo.class);
+
+        from("direct:marshallPojo").marshal(formatPojo);
+        from("direct:unmarshallPojo").unmarshal(formatPojo);
+    }
+
+}
diff --git a/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/TestPojo.java b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/TestPojo.java
new file mode 100644
index 0000000..53be0ca
--- /dev/null
+++ b/integration-tests/jsonb/src/main/java/org/apache/camel/quarkus/component/jsonb/it/TestPojo.java
@@ -0,0 +1,48 @@
+/*
+ * 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.quarkus.component.jsonb.it;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class TestPojo {
+
+    private byte[] name;
+
+    public byte[] getName() {
+        return this.name;
+    }
+
+    public void setName(byte[] name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this.name.equals(((TestPojo) obj).getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return name != null ? name.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return "TestPojo[" + name + "]";
+    }
+}
diff --git a/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbIT.java b/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbIT.java
new file mode 100644
index 0000000..a326c80
--- /dev/null
+++ b/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbIT.java
@@ -0,0 +1,24 @@
+/*
+ * 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.quarkus.component.jsonb.it;
+
+import io.quarkus.test.junit.NativeImageTest;
+
+@NativeImageTest
+class JsonbIT extends JsonbTest {
+
+}
diff --git a/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbTest.java b/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbTest.java
new file mode 100644
index 0000000..116880b
--- /dev/null
+++ b/integration-tests/jsonb/src/test/java/org/apache/camel/quarkus/component/jsonb/it/JsonbTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.quarkus.component.jsonb.it;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@QuarkusTest
+class JsonbTest {
+
+    private final Map MSG = new HashMap() {
+        {
+            put("greeting", "Hello");
+            put("name", "Sheldon");
+        }
+    };
+    private final String MARSHALLED_MSG = "\\{\"greeting\":\"Hello\",\"name\":\"Sheldon\"\\}";
+
+    @Test
+    public void testMap() throws Exception {
+        Map<String, Object> in = new HashMap<>();
+        in.put("greeting", "Hello");
+        in.put("name", serialize("Sheldon"));
+
+        String marshalled = RestAssured.given()
+                .contentType(ContentType.JSON)
+                .body(MSG)
+                .queryParam("route", "in")
+                .post("/jsonb/marshallMap")
+                .then()
+                .statusCode(200)
+                .extract()
+                .asString();
+
+        assertTrue(marshalled.matches(MARSHALLED_MSG),
+                String.format("Expected '%s', but got '%s'", MARSHALLED_MSG, marshalled));
+
+        Map unmarshalled = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body(marshalled)
+                .post("/jsonb/unmarshallMap")
+                .then()
+                .statusCode(200)
+                .extract()
+                .as(Map.class);
+
+        assertTrue(unmarshalled.containsKey("greeting"), "Key 'greeting' should be present.");
+        assertEquals("Hello", unmarshalled.get("greeting"));
+        assertTrue(unmarshalled.containsKey("name"), "Key 'name' should be present.");
+        assertEquals("Sheldon", unmarshalled.get("name"));
+    }
+
+    @Test
+    public void testPojo() throws Exception {
+        String s = RestAssured.given()
+                .contentType(ContentType.BINARY)
+                .body(serialize("Sheldon"))
+                .queryParam("route", "in")
+                .post("/jsonb/marshallPojo")
+                .then()
+                .statusCode(200)
+                .extract()
+                .asString();
+
+        assertTrue(s.matches("\\{\"name\":\".*\"\\}"), String.format("Expected '{\"name\":\".*\"}', but got '%s'", s));
+
+        InputStream is = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body(s)
+                .post("/jsonb/unmarshallPojo")
+                .then()
+                .statusCode(201)
+                .extract()
+                .asInputStream();
+
+        assertEquals("Sheldon", deserialize(is));
+    }
+
+    private byte[] serialize(String s) throws Exception {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+            oos.writeObject(s);
+            return baos.toByteArray();
+        }
+    }
+
+    private Object deserialize(InputStream is) throws Exception {
+        try (ObjectInputStream ois = new ObjectInputStream(is)) {
+            return ois.readObject();
+        }
+    }
+
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index c5ce2ed..1326867 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -116,6 +116,7 @@
         <module>jsch</module>
         <module>jslt</module>
         <module>json-validator</module>
+        <module>jsonb</module>
         <module>jsonpath</module>
         <module>jta</module>
         <module>kafka</module>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index bec05c2..ac6aef3 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -1259,6 +1259,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
+                <artifactId>camel-jsonb</artifactId>
+                <version>${camel.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
                 <artifactId>camel-jsonpath</artifactId>
                 <version>${camel.version}</version>
             </dependency>
@@ -3733,6 +3738,16 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-jsonb</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-jsonb-deployment</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-jsonpath</artifactId>
                 <version>${camel-quarkus.version}</version>
             </dependency>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index c4c65c0..40c90ae 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -68,6 +68,7 @@ dataformats:
   - csv
   - dataformat
   - jaxb
+  - jsonb
   - soap
   - xstream
 foundation:


[camel-quarkus] 01/06: Upgrade to Camel 3.7.0

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

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

commit 5b869762420c9dd0ae0c567eae7db24c4f08cf8a
Author: James Netherton <ja...@gmail.com>
AuthorDate: Mon Oct 19 07:16:38 2020 +0100

    Upgrade to Camel 3.7.0
---
 .../ROOT/pages/reference/extensions/core.adoc      |   1 +
 .../pages/reference/extensions/kubernetes.adoc     |   1 +
 .../ROOT/pages/reference/extensions/leveldb.adoc   |  12 ++-
 .../partials/reference/components/atlasmap.adoc    |   1 +
 .../components/kubernetes-custom-resources.adoc    |  13 +++
 .../partials/reference/dataformats/json-jsonb.adoc |   1 +
 .../ROOT/partials/reference/languages/csimple.adoc |  13 +++
 .../partials/reference/languages/datasonnet.adoc   |   1 +
 .../ROOT/partials/reference/languages/joor.adoc    |   1 +
 .../partials/reference/others/csimple-joor.adoc    |   1 +
 .../partials/reference/others/leveldb-legacy.adoc  |   1 +
 .../quarkus/core/deployment/CamelProcessor.java    |   8 ++
 .../core/runtime/CamelConfigurationTest.java       |   4 +-
 .../core/runtime/CamelInjectionPointTest.java      |   3 -
 extensions-core/core/runtime/pom.xml               |  16 +--
 .../org/apache/camel/quarkus/core/BaseModel.java   |  31 ++++--
 .../quarkus/core/CamelLifecycleEventBridge.java    |  12 ---
 .../camel/quarkus/core/FastCamelContext.java       | 117 +++++++++++++++------
 .../org/apache/camel/quarkus/core/FastModel.java   |   1 -
 .../camel/quarkus/core/FastTypeConverter.java      |   2 +-
 .../camel/quarkus/main/CamelMainRecorder.java      |   5 -
 extensions-support/spring/core/pom.xml             |   1 +
 extensions/json-validator/runtime/pom.xml          |   4 +
 .../leveldb/runtime/src/main/doc/limitations.adoc  |  12 ++-
 .../component/leveldb/ObjectCodecSubstitute.java   |  64 -----------
 .../QuarkusLevelDBAggregationRepository.java       |  71 +++++++++++++
 .../MicroprofileFaultToleranceProcessor.java       |   8 ++
 .../component/qute/QuteComponentConfigurer.java    |  36 ++++---
 .../component/qute/QuteEndpointConfigurer.java     |  38 +++----
 .../component/qute/QuteEndpointUriFactory.java     |   7 +-
 .../org/apache/camel/component/qute/qute.json      |  23 ++--
 .../component/foundation/it/mock/MockResource.java |   4 +-
 .../component/leveldb/it/LeveldbRouteBuilder.java  |  10 +-
 .../quarkus/component/leveldb/it/LeveldbIT.java    |   4 -
 .../quarkus/component/leveldb/it/LeveldbTest.java  |  14 +--
 .../camel/quarkus/main/CoreMainResource.java       |   8 --
 .../main/src/main/resources/application.properties |   5 -
 .../apache/camel/quarkus/main/CoreMainTest.java    |   6 --
 .../camel/quarkus/component/saga/it/SagaRoute.java |   2 +-
 pom.xml                                            |   5 +-
 poms/bom/pom.xml                                   |  10 ++
 41 files changed, 335 insertions(+), 242 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/core.adoc b/docs/modules/ROOT/pages/reference/extensions/core.adoc
index 4449dda..cd8e0a5 100644
--- a/docs/modules/ROOT/pages/reference/extensions/core.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/core.adoc
@@ -18,6 +18,7 @@ Camel core functionality and basic Camel languages: Constant, ExchangeProperty,
 == What's inside
 
 * xref:latest@components:languages:constant-language.adoc[Constant language]
+* xref:latest@components:languages:csimple-language.adoc[CSimple language]
 * xref:latest@components:languages:exchangeProperty-language.adoc[ExchangeProperty language]
 * xref:latest@components:languages:file-language.adoc[File language]
 * xref:latest@components:languages:header-language.adoc[Header language]
diff --git a/docs/modules/ROOT/pages/reference/extensions/kubernetes.adoc b/docs/modules/ROOT/pages/reference/extensions/kubernetes.adoc
index 03778ed..05cfc34 100644
--- a/docs/modules/ROOT/pages/reference/extensions/kubernetes.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/kubernetes.adoc
@@ -18,6 +18,7 @@ Perform operations against Kubernetes API
 == What's inside
 
 * xref:latest@components::kubernetes-config-maps-component.adoc[Kubernetes ConfigMap component], URI syntax: `kubernetes-config-maps:masterUrl`
+* xref:latest@components::kubernetes-custom-resources-component.adoc[Kubernetes Custom Resources component], URI syntax: `kubernetes-custom-resources:masterUrl`
 * xref:latest@components::kubernetes-deployments-component.adoc[Kubernetes Deployments component], URI syntax: `kubernetes-deployments:masterUrl`
 * xref:latest@components::kubernetes-hpa-component.adoc[Kubernetes HPA component], URI syntax: `kubernetes-hpa:masterUrl`
 * xref:latest@components::kubernetes-job-component.adoc[Kubernetes Job component], URI syntax: `kubernetes-job:masterUrl`
diff --git a/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc b/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc
index fda4ef0..190fc8d 100644
--- a/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc
@@ -38,8 +38,14 @@ In native mode the extension uses a port of LevelDB written in Java (https://git
 which is within 10% of the performance of the C++ original. Please upvote https://github.com/apache/camel-quarkus/issues/1911[this issue]
 if you do not like the present state.
 
-This extension does not support binary payloads in native mode since object serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. To work around this limitation, the extension instead uses Jackson serializaton / deserialization.
+Serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. Extension has to use serializationization based
+on Jackson. Aggregation repository in native has to be constructed in one of the following ways:
+
+* Use class `QuarkusLevelDBAggregationRepository` instead of `LevelDBAggregationRepository`.
+* Configure jackson serializer on `LevelDBAggregationRepository` by calling `repo.setSerializer(new JacksonLevelDBSerializer());`
+
+Jackson serializer has limitation towards binary content. If payload object contains binary data (does not concern payloads which are completely binary), Jackson serialization and deserialization won't work correctly.
+To avoid this, define your own jackson serializer/deserealizer via `Module` and provide it to the aggragation repository
+(you can use for example the constructor of `QuarkusLevelDBAggregationRepository`).
 
-The problem will be solved when the camel-leveldb component is refactored to use Jackson and custom
-serializers (see https://issues.apache.org/jira/browse/CAMEL-15679[issue])
 
diff --git a/docs/modules/ROOT/partials/reference/components/atlasmap.adoc b/docs/modules/ROOT/partials/reference/components/atlasmap.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/components/atlasmap.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/docs/modules/ROOT/partials/reference/components/kubernetes-custom-resources.adoc b/docs/modules/ROOT/partials/reference/components/kubernetes-custom-resources.adoc
new file mode 100644
index 0000000..07f368a
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/components/kubernetes-custom-resources.adoc
@@ -0,0 +1,13 @@
+// Do not edit directly!
+// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+:cq-artifact-id: camel-quarkus-kubernetes
+:cq-artifact-id-base: kubernetes
+:cq-native-supported: true
+:cq-status: Stable
+:cq-deprecated: false
+:cq-jvm-since: 1.0.0
+:cq-native-since: 1.0.0
+:cq-camel-part-name: kubernetes-custom-resources
+:cq-camel-part-title: Kubernetes Custom Resources
+:cq-camel-part-description: Perform operations on Kubernetes Custom Resources and get notified on Deployment changes.
+:cq-extension-page-title: Kubernetes
diff --git a/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc b/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/dataformats/json-jsonb.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/docs/modules/ROOT/partials/reference/languages/csimple.adoc b/docs/modules/ROOT/partials/reference/languages/csimple.adoc
new file mode 100644
index 0000000..cfc8a73
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/languages/csimple.adoc
@@ -0,0 +1,13 @@
+// Do not edit directly!
+// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+:cq-artifact-id: camel-quarkus-core
+:cq-artifact-id-base: core
+:cq-native-supported: true
+:cq-status: Stable
+:cq-deprecated: false
+:cq-jvm-since: 0.0.1
+:cq-native-since: 0.0.1
+:cq-camel-part-name: csimple
+:cq-camel-part-title: CSimple
+:cq-camel-part-description: Evaluate a compile simple expression language.
+:cq-extension-page-title: Core
diff --git a/docs/modules/ROOT/partials/reference/languages/datasonnet.adoc b/docs/modules/ROOT/partials/reference/languages/datasonnet.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/languages/datasonnet.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/docs/modules/ROOT/partials/reference/languages/joor.adoc b/docs/modules/ROOT/partials/reference/languages/joor.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/languages/joor.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/docs/modules/ROOT/partials/reference/others/csimple-joor.adoc b/docs/modules/ROOT/partials/reference/others/csimple-joor.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/others/csimple-joor.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/docs/modules/ROOT/partials/reference/others/leveldb-legacy.adoc b/docs/modules/ROOT/partials/reference/others/leveldb-legacy.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/others/leveldb-legacy.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
index 4b542c9..7efea5e 100644
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
@@ -40,6 +40,7 @@ import io.quarkus.deployment.annotations.Overridable;
 import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 import io.quarkus.deployment.recording.RecorderContext;
 import io.quarkus.runtime.RuntimeValue;
 import org.apache.camel.impl.converter.BaseTypeConverterRegistry;
@@ -346,4 +347,11 @@ class CamelProcessor {
                 .map(CamelRoutesBuilderClassBuildItem::new)
                 .collect(Collectors.toList());
     }
+
+    @BuildStep
+    NativeImageResourceBuildItem initResources() {
+        return new NativeImageResourceBuildItem(
+                "META-INF/services/org/apache/camel/bean-processor-factory",
+                "META-INF/services/org/apache/camel/rest-registry-factory");
+    }
 }
diff --git a/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelConfigurationTest.java b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelConfigurationTest.java
index f51c1ca..435a2d5 100644
--- a/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelConfigurationTest.java
+++ b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelConfigurationTest.java
@@ -72,9 +72,9 @@ public class CamelConfigurationTest {
             assertThat(component.getExchangeFormatter()).isInstanceOf(MyExchangeFormatter.class);
         });
 
-        // ensure that no auto-wiring happen
+        // ensure that auto-wiring happens
         assertThat(camelContext.getComponent("log", LogComponent.class)).satisfies(component -> {
-            assertThat(component.getExchangeFormatter()).isNull();
+            assertThat(component.getExchangeFormatter()).isInstanceOf(MyOtherExchangeFormatter.class);
         });
     }
 
diff --git a/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelInjectionPointTest.java b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelInjectionPointTest.java
index e884503..8076634 100644
--- a/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelInjectionPointTest.java
+++ b/extensions-core/core/deployment/src/test/java/org/apache/camel/quarkus/core/runtime/CamelInjectionPointTest.java
@@ -44,10 +44,8 @@ public class CamelInjectionPointTest {
     @Test
     public void testConfigurer() {
         assertThat(configurer.getLog()).isNotNull();
-        assertThat(configurer.getLog().isBasicPropertyBinding()).isTrue();
         assertThat(configurer.getLog().getExchangeFormatter()).isInstanceOf(MyExchangeFormatter.class);
         assertThat(holder.getLog()).isNotNull();
-        assertThat(holder.getLog().isBasicPropertyBinding()).isTrue();
         assertThat(holder.getLog().getExchangeFormatter()).isInstanceOf(MyExchangeFormatter.class);
     }
 
@@ -58,7 +56,6 @@ public class CamelInjectionPointTest {
 
         @PostConstruct
         void setUpLogComponent() {
-            log.setBasicPropertyBinding(true);
             log.setExchangeFormatter(new MyExchangeFormatter());
         }
 
diff --git a/extensions-core/core/runtime/pom.xml b/extensions-core/core/runtime/pom.xml
index 264f22c..33bdc72 100644
--- a/extensions-core/core/runtime/pom.xml
+++ b/extensions-core/core/runtime/pom.xml
@@ -66,27 +66,31 @@
 
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core-engine</artifactId>
+            <artifactId>camel-base</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-base</artifactId>
+            <artifactId>camel-componentdsl</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core-languages</artifactId>
+            <artifactId>camel-core-catalog</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-endpointdsl</artifactId>
+            <artifactId>camel-core-engine</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-componentdsl</artifactId>
+            <artifactId>camel-core-languages</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core-catalog</artifactId>
+            <artifactId>camel-core-processor</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-endpointdsl</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java
index 8ee50e0..df3c89a 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/BaseModel.java
@@ -29,6 +29,7 @@ import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.impl.DefaultModelReifierFactory;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.FaultToleranceConfigurationDefinition;
 import org.apache.camel.model.HystrixConfigurationDefinition;
@@ -46,6 +47,7 @@ import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.spi.ModelReifierFactory;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.util.AntPathMatcher;
 
@@ -53,6 +55,7 @@ public abstract class BaseModel implements Model {
 
     private final CamelContext camelContext;
 
+    private ModelReifierFactory modelReifierFactory = new DefaultModelReifierFactory();
     private final List<RouteDefinition> routeDefinitions = new ArrayList<>();
     private final List<RouteTemplateDefinition> routeTemplateDefinitions = new ArrayList<>();
     private final List<RestDefinition> restDefinitions = new ArrayList<>();
@@ -201,10 +204,11 @@ public abstract class BaseModel implements Model {
             throw new IllegalArgumentException("Cannot find RouteTemplate with id " + routeTemplateId);
         }
 
-        StringJoiner templatesBuilder = new StringJoiner(", ");
         final Map<String, Object> prop = new HashMap<>();
         // include default values first from the template (and validate that we have inputs for all required parameters)
         if (target.getTemplateParameters() != null) {
+            StringJoiner templatesBuilder = new StringJoiner(", ");
+
             for (RouteTemplateParameterDefinition temp : target.getTemplateParameters()) {
                 if (temp.getDefaultValue() != null) {
                     prop.put(temp.getName(), temp.getDefaultValue());
@@ -215,18 +219,19 @@ public abstract class BaseModel implements Model {
                     }
                 }
             }
+            if (templatesBuilder.length() > 0) {
+                throw new IllegalArgumentException(
+                        "Route template " + routeTemplateId + " the following mandatory parameters must be provided: "
+                                + templatesBuilder.toString());
+            }
         }
-        if (templatesBuilder.length() > 0) {
-            throw new IllegalArgumentException(
-                    "Route template " + routeTemplateId + " the following mandatory parameters must be provided: "
-                            + templatesBuilder.toString());
-        }
+
         // then override with user parameters
         if (parameters != null) {
             prop.putAll(parameters);
         }
 
-        RouteTemplateDefinition.Converter converter = RouteTemplateDefinition::asRouteDefinition;
+        RouteTemplateDefinition.Converter converter = RouteTemplateDefinition.Converter.DEFAULT_CONVERTER;
 
         for (Map.Entry<String, RouteTemplateDefinition.Converter> entry : routeTemplateConverters.entrySet()) {
             final String key = entry.getKey();
@@ -244,7 +249,7 @@ public abstract class BaseModel implements Model {
             }
         }
 
-        RouteDefinition def = converter.apply(target);
+        RouteDefinition def = converter.apply(target, prop);
         if (routeId != null) {
             def.setId(routeId);
         }
@@ -476,6 +481,16 @@ public abstract class BaseModel implements Model {
         return modelLifecycleStrategies;
     }
 
+    @Override
+    public ModelReifierFactory getModelReifierFactory() {
+        return modelReifierFactory;
+    }
+
+    @Override
+    public void setModelReifierFactory(ModelReifierFactory modelReifierFactory) {
+        this.modelReifierFactory = modelReifierFactory;
+    }
+
     /**
      * Should we start newly added routes?
      */
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelLifecycleEventBridge.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelLifecycleEventBridge.java
index 8b535b1..a675ed9 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelLifecycleEventBridge.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelLifecycleEventBridge.java
@@ -26,8 +26,6 @@ import io.quarkus.arc.Arc;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
-import org.apache.camel.ErrorHandlerFactory;
-import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.Service;
 import org.apache.camel.VetoCamelContextStartException;
@@ -96,16 +94,6 @@ public class CamelLifecycleEventBridge implements LifecycleStrategy {
     }
 
     @Override
-    public void onErrorHandlerAdd(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerFactory) {
-        fireEvent(new ErrorHandlerAddEvent(route, errorHandler, errorHandlerFactory));
-    }
-
-    @Override
-    public void onErrorHandlerRemove(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerFactory) {
-        fireEvent(new ErrorHandlerRemoveEvent(route, errorHandler, errorHandlerFactory));
-    }
-
-    @Override
     public void onThreadPoolAdd(CamelContext camelContext, ThreadPoolExecutor threadPool, String id,
             String sourceId, String routeId, String threadPoolProfileId) {
         fireEvent(new ThreadPoolAddEvent(camelContext, threadPool, id, sourceId, routeId, threadPoolProfileId));
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
index 4ca613e..fd96350 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
@@ -22,10 +22,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.ExecutorService;
 import java.util.function.Function;
 
-import org.apache.camel.AsyncProcessor;
 import org.apache.camel.CatalogCamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
@@ -36,12 +34,12 @@ import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.ValueHolder;
+import org.apache.camel.builder.AdviceWith;
 import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.catalog.impl.DefaultRuntimeCamelCatalog;
 import org.apache.camel.component.microprofile.config.CamelMicroProfilePropertiesSource;
 import org.apache.camel.health.HealthCheckRegistry;
-import org.apache.camel.impl.DefaultExecutorServiceManager;
 import org.apache.camel.impl.engine.AbstractCamelContext;
 import org.apache.camel.impl.engine.BaseServiceResolver;
 import org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager;
@@ -54,17 +52,19 @@ import org.apache.camel.impl.engine.DefaultComponentResolver;
 import org.apache.camel.impl.engine.DefaultConfigurerResolver;
 import org.apache.camel.impl.engine.DefaultDataFormatResolver;
 import org.apache.camel.impl.engine.DefaultEndpointRegistry;
+import org.apache.camel.impl.engine.DefaultExecutorServiceManager;
 import org.apache.camel.impl.engine.DefaultHeadersMapFactory;
 import org.apache.camel.impl.engine.DefaultInflightRepository;
 import org.apache.camel.impl.engine.DefaultInjector;
+import org.apache.camel.impl.engine.DefaultInterceptEndpointFactory;
 import org.apache.camel.impl.engine.DefaultLanguageResolver;
 import org.apache.camel.impl.engine.DefaultMessageHistoryFactory;
 import org.apache.camel.impl.engine.DefaultNodeIdFactory;
 import org.apache.camel.impl.engine.DefaultPackageScanClassResolver;
 import org.apache.camel.impl.engine.DefaultPackageScanResourceResolver;
-import org.apache.camel.impl.engine.DefaultProcessorFactory;
 import org.apache.camel.impl.engine.DefaultReactiveExecutor;
 import org.apache.camel.impl.engine.DefaultRouteController;
+import org.apache.camel.impl.engine.DefaultRouteFactory;
 import org.apache.camel.impl.engine.DefaultStreamCachingStrategy;
 import org.apache.camel.impl.engine.DefaultTracer;
 import org.apache.camel.impl.engine.DefaultTransformerRegistry;
@@ -73,8 +73,8 @@ import org.apache.camel.impl.engine.DefaultUriFactoryResolver;
 import org.apache.camel.impl.engine.DefaultValidatorRegistry;
 import org.apache.camel.impl.engine.EndpointKey;
 import org.apache.camel.impl.engine.RouteService;
-import org.apache.camel.impl.transformer.TransformerKey;
-import org.apache.camel.impl.validator.ValidatorKey;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.impl.engine.ValidatorKey;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.FaultToleranceConfigurationDefinition;
 import org.apache.camel.model.HystrixConfigurationDefinition;
@@ -91,12 +91,16 @@ import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
-import org.apache.camel.processor.MulticastProcessor;
+import org.apache.camel.processor.DefaultAnnotationBasedProcessorFactory;
+import org.apache.camel.processor.DefaultDeferServiceFactory;
+import org.apache.camel.processor.DefaultInternalProcessorFactory;
+import org.apache.camel.processor.DefaultProcessorFactory;
 import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.reifier.language.ExpressionReifier;
 import org.apache.camel.reifier.transformer.TransformerReifier;
 import org.apache.camel.reifier.validator.ValidatorReifier;
+import org.apache.camel.spi.AnnotationBasedProcessorFactory;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
 import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.BeanProcessorFactory;
@@ -110,17 +114,21 @@ import org.apache.camel.spi.ConfigurerResolver;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DeferServiceFactory;
 import org.apache.camel.spi.EndpointRegistry;
 import org.apache.camel.spi.ExecutorServiceManager;
 import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.HeadersMapFactory;
 import org.apache.camel.spi.InflightRepository;
 import org.apache.camel.spi.Injector;
+import org.apache.camel.spi.InterceptEndpointFactory;
+import org.apache.camel.spi.InternalProcessorFactory;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.ManagementNameStrategy;
 import org.apache.camel.spi.MessageHistoryFactory;
 import org.apache.camel.spi.ModelJAXBContextFactory;
+import org.apache.camel.spi.ModelReifierFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
@@ -132,6 +140,7 @@ import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.RestBindingJaxbDataFormatFactory;
 import org.apache.camel.spi.RestRegistryFactory;
 import org.apache.camel.spi.RouteController;
+import org.apache.camel.spi.RouteFactory;
 import org.apache.camel.spi.ShutdownStrategy;
 import org.apache.camel.spi.StreamCachingStrategy;
 import org.apache.camel.spi.Tracer;
@@ -150,7 +159,7 @@ import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 
 public class FastCamelContext extends AbstractCamelContext implements CatalogCamelContext, ModelCamelContext {
-    private final Model model;
+    private Model model;
     private final String version;
     private final XMLRoutesDefinitionLoader xmlLoader;
     private final ModelToXMLDumper modelDumper;
@@ -275,6 +284,21 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
     }
 
     @Override
+    protected InternalProcessorFactory createInternalProcessorFactory() {
+        return new DefaultInternalProcessorFactory();
+    }
+
+    @Override
+    protected InterceptEndpointFactory createInterceptEndpointFactory() {
+        return new DefaultInterceptEndpointFactory();
+    }
+
+    @Override
+    protected RouteFactory createRouteFactory() {
+        return new DefaultRouteFactory();
+    }
+
+    @Override
     protected MessageHistoryFactory createMessageHistoryFactory() {
         return new DefaultMessageHistoryFactory();
     }
@@ -320,18 +344,30 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
 
     @Override
     protected BeanProxyFactory createBeanProxyFactory() {
-        return new BaseServiceResolver<>(BeanProxyFactory.FACTORY, BeanProxyFactory.class)
-                .resolve(getCamelContextReference())
-                .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProxyFactory on classpath. "
-                        + "Add camel-bean to classpath."));
+        return new BaseServiceResolver<>(BeanProxyFactory.FACTORY, BeanProxyFactory.class,
+                getBootstrapFactoryFinder())
+                        .resolve(getCamelContextReference())
+                        .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProxyFactory on classpath. "
+                                + "Add camel-bean to classpath."));
+    }
+
+    @Override
+    protected AnnotationBasedProcessorFactory createAnnotationBasedProcessorFactory() {
+        return new DefaultAnnotationBasedProcessorFactory();
+    }
+
+    @Override
+    protected DeferServiceFactory createDeferServiceFactory() {
+        return new DefaultDeferServiceFactory();
     }
 
     @Override
     protected BeanProcessorFactory createBeanProcessorFactory() {
-        return new BaseServiceResolver<>(BeanProcessorFactory.FACTORY, BeanProcessorFactory.class)
-                .resolve(getCamelContextReference())
-                .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProcessorFactory on classpath. "
-                        + "Add camel-bean to classpath."));
+        return new BaseServiceResolver<>(BeanProcessorFactory.FACTORY, BeanProcessorFactory.class,
+                getBootstrapFactoryFinder())
+                        .resolve(getCamelContextReference())
+                        .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProcessorFactory on classpath. "
+                                + "Add camel-bean to classpath."));
     }
 
     @Override
@@ -393,10 +429,11 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
 
     @Override
     protected RestRegistryFactory createRestRegistryFactory() {
-        return new BaseServiceResolver<>(RestRegistryFactory.FACTORY, RestRegistryFactory.class)
-                .resolve(getCamelContextReference())
-                .orElseThrow(() -> new IllegalArgumentException("Cannot find RestRegistryFactory on classpath. "
-                        + "Add camel-rest to classpath."));
+        return new BaseServiceResolver<>(RestRegistryFactory.FACTORY, RestRegistryFactory.class,
+                getBootstrapFactoryFinder())
+                        .resolve(getCamelContextReference())
+                        .orElseThrow(() -> new IllegalArgumentException("Cannot find RestRegistryFactory on classpath. "
+                                + "Add camel-rest to classpath."));
     }
 
     @Override
@@ -425,14 +462,6 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
     }
 
     @Override
-    public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor,
-            boolean shutdownExecutorService) {
-        return new MulticastProcessor(getCamelContextReference(), null, processors, null,
-                true, executor, shutdownExecutorService, false, false,
-                0, null, false, false);
-    }
-
-    @Override
     protected ConfigurerResolver createConfigurerResolver() {
         return new DefaultConfigurerResolver();
     }
@@ -444,8 +473,9 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
 
     @Override
     protected HealthCheckRegistry createHealthCheckRegistry() {
-        return new BaseServiceResolver<>(HealthCheckRegistry.FACTORY, HealthCheckRegistry.class)
-                .resolve(getCamelContextReference()).orElse(null);
+        return new BaseServiceResolver<>(HealthCheckRegistry.FACTORY, HealthCheckRegistry.class,
+                getBootstrapFactoryFinder())
+                        .resolve(getCamelContextReference()).orElse(null);
     }
 
     @Override
@@ -455,10 +485,12 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
 
     @Override
     protected RestBindingJaxbDataFormatFactory createRestBindingJaxbDataFormatFactory() {
-        return new BaseServiceResolver<>(RestBindingJaxbDataFormatFactory.FACTORY, RestBindingJaxbDataFormatFactory.class)
-                .resolve(getCamelContextReference())
-                .orElseThrow(() -> new IllegalArgumentException("Cannot find RestBindingJaxbDataFormatFactory on classpath. "
-                        + "Add camel-jaxb to classpath."));
+        return new BaseServiceResolver<>(RestBindingJaxbDataFormatFactory.FACTORY, RestBindingJaxbDataFormatFactory.class,
+                getBootstrapFactoryFinder())
+                        .resolve(getCamelContextReference())
+                        .orElseThrow(
+                                () -> new IllegalArgumentException("Cannot find RestBindingJaxbDataFormatFactory on classpath. "
+                                        + "Add camel-jaxb to classpath."));
     }
 
     @Override
@@ -576,6 +608,11 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
                 .createErrorHandler(processor);
     }
 
+    @Override
+    public void disposeModel() {
+        this.model = null;
+    }
+
     //
     // ModelCamelContext
     //
@@ -804,6 +841,16 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
     }
 
     @Override
+    public ModelReifierFactory getModelReifierFactory() {
+        return model.getModelReifierFactory();
+    }
+
+    @Override
+    public void setModelReifierFactory(ModelReifierFactory modelReifierFactory) {
+        model.setModelReifierFactory(modelReifierFactory);
+    }
+
+    @Override
     public void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception {
         // indicate we are staring the route using this thread so
         // we are able to query this if needed
@@ -860,7 +907,7 @@ public class FastCamelContext extends AbstractCamelContext implements CatalogCam
 
     @Override
     public RouteDefinition adviceWith(RouteDefinition definition, AdviceWithRouteBuilder builder) throws Exception {
-        return RouteReifier.adviceWith(definition, this, builder);
+        return AdviceWith.adviceWith(definition, this, builder);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java
index fd299a8..f266f57 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastModel.java
@@ -22,5 +22,4 @@ public class FastModel extends BaseModel {
     public FastModel(CamelContext camelContext) {
         super(camelContext);
     }
-
 }
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java
index 6492338..2df9239 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastTypeConverter.java
@@ -25,7 +25,7 @@ public class FastTypeConverter extends DefaultTypeConverter {
     private static final Logger LOG = LoggerFactory.getLogger(FastTypeConverter.class);
 
     public FastTypeConverter() {
-        super(null, null, null, null, false);
+        super(null, null, null, false);
     }
 
     @Override
diff --git a/extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRecorder.java b/extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRecorder.java
index d7ba558..0b3e65c 100644
--- a/extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRecorder.java
+++ b/extensions-core/main/runtime/src/main/java/org/apache/camel/quarkus/main/CamelMainRecorder.java
@@ -42,11 +42,6 @@ public class CamelMainRecorder {
         main.setRoutesCollector(routesCollector.getValue());
         main.addMainListener(new CamelMainEventBridge());
 
-        // autowire only non null values as components may have configured
-        // through CDI or from a Build Item thus those values should not be
-        // overridden
-        main.configure().setAutowireComponentPropertiesNonNullOnly(true);
-
         // properties are loaded through MicroProfile Config so there's
         // no need to look for sources.
         main.setDefaultPropertyPlaceholderLocation("false");
diff --git a/extensions-support/spring/core/pom.xml b/extensions-support/spring/core/pom.xml
index 529cf72..a2794dd 100644
--- a/extensions-support/spring/core/pom.xml
+++ b/extensions-support/spring/core/pom.xml
@@ -77,6 +77,7 @@
                                         <include>org/springframework/core/env/**</include>
                                         <include>org/springframework/core/io/**</include>
                                         <include>org/springframework/core/log/**</include>
+                                        <include>org/springframework/core/metrics/**</include>
                                         <include>org/springframework/core/task/**</include>
                                         <include>org/springframework/lang/**</include>
                                         <include>org/springframework/util/*</include>
diff --git a/extensions/json-validator/runtime/pom.xml b/extensions/json-validator/runtime/pom.xml
index 1d10f1b..e33f884 100644
--- a/extensions/json-validator/runtime/pom.xml
+++ b/extensions/json-validator/runtime/pom.xml
@@ -56,6 +56,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-json-validator</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.jruby.joni</groupId>
+            <artifactId>joni</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/extensions/leveldb/runtime/src/main/doc/limitations.adoc b/extensions/leveldb/runtime/src/main/doc/limitations.adoc
index e7ebff9..9b74c99 100644
--- a/extensions/leveldb/runtime/src/main/doc/limitations.adoc
+++ b/extensions/leveldb/runtime/src/main/doc/limitations.adoc
@@ -2,7 +2,13 @@ In native mode the extension uses a port of LevelDB written in Java (https://git
 which is within 10% of the performance of the C++ original. Please upvote https://github.com/apache/camel-quarkus/issues/1911[this issue]
 if you do not like the present state.
 
-This extension does not support binary payloads in native mode since object serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. To work around this limitation, the extension instead uses Jackson serializaton / deserialization.
+Serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. Extension has to use serializationization based
+on Jackson. Aggregation repository in native has to be constructed in one of the following ways:
+
+* Use class `QuarkusLevelDBAggregationRepository` instead of `LevelDBAggregationRepository`.
+* Configure jackson serializer on `LevelDBAggregationRepository` by calling `repo.setSerializer(new JacksonLevelDBSerializer());`
+
+Jackson serializer has limitation towards binary content. If payload object contains binary data (does not concern payloads which are completely binary), Jackson serialization and deserialization won't work correctly.
+To avoid this, define your own jackson serializer/deserealizer via `Module` and provide it to the aggragation repository
+(you can use for example the constructor of `QuarkusLevelDBAggregationRepository`).
 
-The problem will be solved when the camel-leveldb component is refactored to use Jackson and custom
-serializers (see https://issues.apache.org/jira/browse/CAMEL-15679[issue])
diff --git a/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/ObjectCodecSubstitute.java b/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/ObjectCodecSubstitute.java
deleted file mode 100644
index 8ab38a4..0000000
--- a/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/ObjectCodecSubstitute.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.quarkus.component.leveldb;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.oracle.svm.core.annotate.Inject;
-import com.oracle.svm.core.annotate.Substitute;
-import com.oracle.svm.core.annotate.TargetClass;
-import org.apache.camel.support.DefaultExchangeHolder;
-import org.fusesource.hawtbuf.codec.ObjectCodec;
-
-/**
- * This os workaround for serialization of DefaultExchangeHolder.
- * Once serialization is implemented in graalVM (see https://github.com/oracle/graal/issues/460), this substitution
- * could
- * be removed.
- */
-@TargetClass(value = ObjectCodec.class)
-final class ObjectCodecSubstitute {
-
-    @Inject
-    private ObjectMapper objectMapper;
-
-    @Substitute
-    public void encode(Object object, DataOutput dataOut) throws IOException {
-        if (objectMapper == null) {
-            objectMapper = new ObjectMapper();
-            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
-            objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
-        }
-        objectMapper.writeValue(dataOut, object);
-    }
-
-    @Substitute
-    public Object decode(DataInput dataIn) throws IOException {
-        if (objectMapper == null) {
-            objectMapper = new ObjectMapper();
-            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
-            objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
-        }
-        return objectMapper.readValue(dataIn, DefaultExchangeHolder.class);
-    }
-
-}
diff --git a/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java b/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java
new file mode 100644
index 0000000..7e930ec
--- /dev/null
+++ b/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java
@@ -0,0 +1,71 @@
+/*
+ * 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.quarkus.component.leveldb;
+
+import com.fasterxml.jackson.databind.Module;
+import org.apache.camel.component.leveldb.LevelDBAggregationRepository;
+import org.apache.camel.component.leveldb.LevelDBFile;
+import org.apache.camel.component.leveldb.serializer.JacksonLevelDBSerializer;
+
+public class QuarkusLevelDBAggregationRepository extends LevelDBAggregationRepository {
+
+    public QuarkusLevelDBAggregationRepository() {
+        initSerializer(null);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName) {
+        super(repositoryName);
+        initSerializer(null);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName, String persistentFileName) {
+        super(repositoryName, persistentFileName);
+        initSerializer(null);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName, LevelDBFile levelDBFile) {
+        super(repositoryName, levelDBFile);
+        initSerializer(null);
+    }
+
+    //constructor with module
+
+    public QuarkusLevelDBAggregationRepository(Module module) {
+        JacksonLevelDBSerializer serializer = new JacksonLevelDBSerializer(module);
+        initSerializer(module);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName, Module module) {
+        super(repositoryName);
+        initSerializer(module);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName, String persistentFileName, Module module) {
+        super(repositoryName, persistentFileName);
+        initSerializer(module);
+    }
+
+    public QuarkusLevelDBAggregationRepository(String repositoryName, LevelDBFile levelDBFile, Module module) {
+        super(repositoryName, levelDBFile);
+        initSerializer(module);
+    }
+
+    private void initSerializer(Module module) {
+        JacksonLevelDBSerializer serializer = new JacksonLevelDBSerializer(module);
+        setSerializer(serializer);
+    }
+}
diff --git a/extensions/microprofile-fault-tolerance/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/fault/tolerance/deployment/MicroprofileFaultToleranceProcessor.java b/extensions/microprofile-fault-tolerance/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/fault/tolerance/deployment/MicroprofileFaultToleranceProcessor.java
index d5b8b14..05673b1 100644
--- a/extensions/microprofile-fault-tolerance/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/fault/tolerance/deployment/MicroprofileFaultToleranceProcessor.java
+++ b/extensions/microprofile-fault-tolerance/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/fault/tolerance/deployment/MicroprofileFaultToleranceProcessor.java
@@ -18,6 +18,7 @@ package org.apache.camel.quarkus.component.microprofile.fault.tolerance.deployme
 
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 
 class MicroprofileFaultToleranceProcessor {
 
@@ -27,4 +28,11 @@ class MicroprofileFaultToleranceProcessor {
     FeatureBuildItem feature() {
         return new FeatureBuildItem(FEATURE);
     }
+
+    @BuildStep
+    NativeImageResourceBuildItem initResources() {
+        return new NativeImageResourceBuildItem(
+                "META-INF/services/org/apache/camel/model/CircuitBreakerDefinition");
+    }
+
 }
diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java
index 95e6cc2..76a8a82 100644
--- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java
+++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java
@@ -4,8 +4,10 @@ package org.apache.camel.component.qute;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
 import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
 import org.apache.camel.util.CaseInsensitiveMap;
 import org.apache.camel.support.component.PropertyConfigurerSupport;
 
@@ -15,24 +17,14 @@ import org.apache.camel.support.component.PropertyConfigurerSupport;
 @SuppressWarnings("unchecked")
 public class QuteComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
 
-    private static final Map<String, Object> ALL_OPTIONS;
-    static {
-        Map<String, Object> map = new CaseInsensitiveMap();
-        map.put("allowTemplateFromHeader", boolean.class);
-        map.put("lazyStartProducer", boolean.class);
-        map.put("basicPropertyBinding", boolean.class);
-        map.put("quteEngine", io.quarkus.qute.Engine.class);
-        ALL_OPTIONS = map;
-    }
-
     @Override
     public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
         QuteComponent target = (QuteComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowtemplatefromheader":
         case "allowTemplateFromHeader": target.setAllowTemplateFromHeader(property(camelContext, boolean.class, value)); return true;
-        case "basicpropertybinding":
-        case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true;
+        case "autowiredenabled":
+        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
         case "quteengine":
@@ -42,8 +34,18 @@ public class QuteComponentConfigurer extends PropertyConfigurerSupport implement
     }
 
     @Override
-    public Map<String, Object> getAllOptions(Object target) {
-        return ALL_OPTIONS;
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return boolean.class;
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "quteengine":
+        case "quteEngine": return io.quarkus.qute.Engine.class;
+        default: return null;
+        }
     }
 
     @Override
@@ -52,8 +54,8 @@ public class QuteComponentConfigurer extends PropertyConfigurerSupport implement
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowtemplatefromheader":
         case "allowTemplateFromHeader": return target.isAllowTemplateFromHeader();
-        case "basicpropertybinding":
-        case "basicPropertyBinding": return target.isBasicPropertyBinding();
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "quteengine":
diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java
index 983fa1c..ff14a7c 100644
--- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java
+++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java
@@ -4,8 +4,10 @@ package org.apache.camel.component.qute;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
 import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
 import org.apache.camel.util.CaseInsensitiveMap;
 import org.apache.camel.support.component.PropertyConfigurerSupport;
 
@@ -15,20 +17,6 @@ import org.apache.camel.support.component.PropertyConfigurerSupport;
 @SuppressWarnings("unchecked")
 public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
 
-    private static final Map<String, Object> ALL_OPTIONS;
-    static {
-        Map<String, Object> map = new CaseInsensitiveMap();
-        map.put("resourceUri", java.lang.String.class);
-        map.put("allowContextMapAll", boolean.class);
-        map.put("allowTemplateFromHeader", boolean.class);
-        map.put("contentCache", boolean.class);
-        map.put("encoding", java.lang.String.class);
-        map.put("lazyStartProducer", boolean.class);
-        map.put("basicPropertyBinding", boolean.class);
-        map.put("synchronous", boolean.class);
-        ALL_OPTIONS = map;
-    }
-
     @Override
     public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
         QuteEndpoint target = (QuteEndpoint) obj;
@@ -37,8 +25,6 @@ public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements
         case "allowContextMapAll": target.setAllowContextMapAll(property(camelContext, boolean.class, value)); return true;
         case "allowtemplatefromheader":
         case "allowTemplateFromHeader": target.setAllowTemplateFromHeader(property(camelContext, boolean.class, value)); return true;
-        case "basicpropertybinding":
-        case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true;
         case "contentcache":
         case "contentCache": target.setContentCache(property(camelContext, boolean.class, value)); return true;
         case "encoding": target.setEncoding(property(camelContext, java.lang.String.class, value)); return true;
@@ -50,8 +36,20 @@ public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements
     }
 
     @Override
-    public Map<String, Object> getAllOptions(Object target) {
-        return ALL_OPTIONS;
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontextmapall":
+        case "allowContextMapAll": return boolean.class;
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return boolean.class;
+        case "contentcache":
+        case "contentCache": return boolean.class;
+        case "encoding": return java.lang.String.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "synchronous": return boolean.class;
+        default: return null;
+        }
     }
 
     @Override
@@ -62,8 +60,6 @@ public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements
         case "allowContextMapAll": return target.isAllowContextMapAll();
         case "allowtemplatefromheader":
         case "allowTemplateFromHeader": return target.isAllowTemplateFromHeader();
-        case "basicpropertybinding":
-        case "basicPropertyBinding": return target.isBasicPropertyBinding();
         case "contentcache":
         case "contentCache": return target.isContentCache();
         case "encoding": return target.getEncoding();
diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointUriFactory.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointUriFactory.java
index f24c41f..3ab0ef8 100644
--- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointUriFactory.java
+++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointUriFactory.java
@@ -20,8 +20,7 @@ public class QuteEndpointUriFactory extends org.apache.camel.support.component.E
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(8);
-        props.add("basicPropertyBinding");
+        Set<String> props = new HashSet<>(7);
         props.add("allowTemplateFromHeader");
         props.add("lazyStartProducer");
         props.add("synchronous");
@@ -39,14 +38,14 @@ public class QuteEndpointUriFactory extends org.apache.camel.support.component.E
     }
 
     @Override
-    public String buildUri(String scheme, Map<String, Object> properties) throws URISyntaxException {
+    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
         String syntax = scheme + BASE;
         String uri = syntax;
 
         Map<String, Object> copy = new HashMap<>(properties);
 
         uri = buildPathParameter(syntax, uri, "resourceUri", null, true, copy);
-        uri = buildQueryParameters(uri, copy);
+        uri = buildQueryParameters(uri, copy, encode);
         return uri;
     }
 
diff --git a/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json b/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json
index eda01b3..ebebb4c 100644
--- a/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json
+++ b/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json
@@ -22,19 +22,18 @@
     "lenientProperties": false
   },
   "componentProperties": {
-    "allowTemplateFromHeader": { "kind": "property", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the head [...]
-    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the r [...]
-    "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": true, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" },
-    "quteEngine": { "kind": "property", "displayName": "Qute Engine", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "io.quarkus.qute.Engine", "deprecated": false, "secret": false, "description": "To use the Engine otherwise a new engine is created" }
+    "allowTemplateFromHeader": { "kind": "property", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulne [...]
+    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during star [...]
+    "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...]
+    "quteEngine": { "kind": "property", "displayName": "Qute Engine", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "io.quarkus.qute.Engine", "deprecated": false, "autowired": false, "secret": false, "description": "To use the Engine otherwise a new engine is created" }
   },
   "properties": {
-    "resourceUri": { "kind": "path", "displayName": "Resource Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "description": "Path to the resource. You can prefix with: classpath, file, http, ref, or bean. classpath, file and http loads the resource using these protocols (classpath is default). ref will lookup the resource in the registry. bean will call a method on a  [...]
-    "allowContextMapAll": { "kind": "parameter", "displayName": "Allow Context Map All", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Sets whether the context map should allow access to all details. By default only the message body and headers can be accessed. This option can be enabled for full access to the current Exchange and CamelContext. Doing so impose a p [...]
-    "allowTemplateFromHeader": { "kind": "parameter", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the hea [...]
-    "contentCache": { "kind": "parameter", "displayName": "Content Cache", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Sets whether to use resource content cache or not" },
-    "encoding": { "kind": "parameter", "displayName": "Encoding", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Character encoding of the resource content." },
-    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the  [...]
-    "basicPropertyBinding": { "kind": "parameter", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" },
-    "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." }
+    "resourceUri": { "kind": "path", "displayName": "Resource Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Path to the resource. You can prefix with: classpath, file, http, ref, or bean. classpath, file and http loads the resource using these protocols (classpath is default). ref will lookup the resource in the registry. bean will [...]
+    "allowContextMapAll": { "kind": "parameter", "displayName": "Allow Context Map All", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether the context map should allow access to all details. By default only the message body and headers can be accessed. This option can be enabled for full access to the current Exchange and CamelContext. [...]
+    "allowTemplateFromHeader": { "kind": "parameter", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vuln [...]
+    "contentCache": { "kind": "parameter", "displayName": "Content Cache", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether to use resource content cache or not" },
+    "encoding": { "kind": "parameter", "displayName": "Encoding", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Character encoding of the resource content." },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
+    "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." }
   }
 }
diff --git a/integration-tests/foundation/src/main/java/org/apache/camel/quarkus/component/foundation/it/mock/MockResource.java b/integration-tests/foundation/src/main/java/org/apache/camel/quarkus/component/foundation/it/mock/MockResource.java
index 6d0e29c..985a507 100644
--- a/integration-tests/foundation/src/main/java/org/apache/camel/quarkus/component/foundation/it/mock/MockResource.java
+++ b/integration-tests/foundation/src/main/java/org/apache/camel/quarkus/component/foundation/it/mock/MockResource.java
@@ -26,10 +26,10 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.AdviceWith;
 import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.model.ModelCamelContext;
-import org.apache.camel.reifier.RouteReifier;
 import org.jboss.logging.Logger;
 import org.wildfly.common.Assert;
 
@@ -51,7 +51,7 @@ public class MockResource {
 
         // advice the first route using the inlined AdviceWith route builder
         // which has extended capabilities than the regular route builder
-        RouteReifier.adviceWith(context.adapt(ModelCamelContext.class).getRouteDefinition("forMocking"), context,
+        AdviceWith.adviceWith(context.adapt(ModelCamelContext.class).getRouteDefinition("forMocking"), context,
                 new AdviceWithRouteBuilder() {
                     @Override
                     public void configure() throws Exception {
diff --git a/integration-tests/leveldb/src/main/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbRouteBuilder.java b/integration-tests/leveldb/src/main/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbRouteBuilder.java
index ed9674f..a5f7b8b 100644
--- a/integration-tests/leveldb/src/main/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbRouteBuilder.java
+++ b/integration-tests/leveldb/src/main/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbRouteBuilder.java
@@ -24,6 +24,7 @@ import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.leveldb.LevelDBAggregationRepository;
+import org.apache.camel.quarkus.component.leveldb.QuarkusLevelDBAggregationRepository;
 
 public class LeveldbRouteBuilder extends RouteBuilder {
     public static final String DIRECT_START = "direct:start";
@@ -39,21 +40,22 @@ public class LeveldbRouteBuilder extends RouteBuilder {
 
     @Override
     public void configure() throws Exception {
-        LevelDBAggregationRepository repo = new LevelDBAggregationRepository("repo", DATA_FOLDER + "leveldb.dat");
+        LevelDBAggregationRepository repo = new QuarkusLevelDBAggregationRepository("repo", DATA_FOLDER + "leveldb.dat");
 
         from(DIRECT_START)
                 .aggregate(header("id"), new MyAggregationStrategy())
                 .completionSize(7).aggregationRepository(repo)
                 .to(MOCK_RESULT);
 
-        LevelDBAggregationRepository repoBinary = new LevelDBAggregationRepository("repo", DATA_FOLDER + "levelBinarydb.dat");
+        LevelDBAggregationRepository repoBinary = new QuarkusLevelDBAggregationRepository("repo",
+                DATA_FOLDER + "levelBinarydb.dat");
 
         from(DIRECT_BINARY)
                 .aggregate(header("id"), new BinaryAggregationStrategy())
                 .completionSize(3).aggregationRepository(repoBinary)
                 .to(MOCK_RESULT);
 
-        LevelDBAggregationRepository repoWithFailure = new LevelDBAggregationRepository("repoWithFailure",
+        LevelDBAggregationRepository repoWithFailure = new QuarkusLevelDBAggregationRepository("repoWithFailure",
                 DATA_FOLDER + "leveldbWithFailure.dat");
 
         repoWithFailure.setUseRecovery(true);
@@ -72,7 +74,7 @@ public class LeveldbRouteBuilder extends RouteBuilder {
                 .to(MOCK_RESULT)
                 .end();
 
-        LevelDBAggregationRepository repoDeadLetter = new LevelDBAggregationRepository("repoDeadLetter",
+        LevelDBAggregationRepository repoDeadLetter = new QuarkusLevelDBAggregationRepository("repoDeadLetter",
                 DATA_FOLDER + "leveldbDeadLetter.dat");
 
         repoDeadLetter.setUseRecovery(true);
diff --git a/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbIT.java b/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbIT.java
index e4fc4ba..743e2ab 100644
--- a/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbIT.java
+++ b/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbIT.java
@@ -20,8 +20,4 @@ import io.quarkus.test.junit.NativeImageTest;
 
 @NativeImageTest
 class LeveldbIT extends LeveldbTest {
-    @Override
-    boolean doeasBinaryDataWork() {
-        return false;
-    }
 }
diff --git a/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbTest.java b/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbTest.java
index 1ffa037..3d473b8 100644
--- a/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbTest.java
+++ b/integration-tests/leveldb/src/test/java/org/apache/camel/quarkus/component/leveldb/it/LeveldbTest.java
@@ -101,19 +101,7 @@ class LeveldbTest {
                 .statusCode(201)
                 .extract().as(Boolean.class);
 
-        if (doeasBinaryDataWork()) {
-            assertTrue(theSame);
-        } else {
-            assertFalse(theSame);
-        }
-    }
-
-    /**
-     * Until binary payload is not supported, in native binary test will fail.
-     * Needs https://issues.apache.org/jira/browse/CAMEL-15679
-     */
-    boolean doeasBinaryDataWork() {
-        return true;
+        assertTrue(theSame);
     }
 
     private Map<String, List<Map<String, Object>>> testAggregate(String path, List<String> messages) {
diff --git a/integration-tests/main/src/main/java/org/apache/camel/quarkus/main/CoreMainResource.java b/integration-tests/main/src/main/java/org/apache/camel/quarkus/main/CoreMainResource.java
index e024201..3c7c97b 100644
--- a/integration-tests/main/src/main/java/org/apache/camel/quarkus/main/CoreMainResource.java
+++ b/integration-tests/main/src/main/java/org/apache/camel/quarkus/main/CoreMainResource.java
@@ -36,7 +36,6 @@ import javax.ws.rs.core.MediaType;
 import org.apache.camel.Component;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.component.log.LogComponent;
-import org.apache.camel.component.timer.TimerComponent;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.quarkus.core.FastFactoryFinderResolver;
 import org.apache.camel.quarkus.it.support.typeconverter.MyPair;
@@ -65,13 +64,6 @@ public class CoreMainResource {
         return main.getCamelContext().resolvePropertyPlaceholders("{{" + name + "}}");
     }
 
-    @Path("/timer/property-binding")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public boolean timerResolvePropertyPlaceholders() throws Exception {
-        return main.getCamelContext().getComponent("timer", TimerComponent.class).isBasicPropertyBinding();
-    }
-
     @Path("/registry/log/exchange-formatter")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
diff --git a/integration-tests/main/src/main/resources/application.properties b/integration-tests/main/src/main/resources/application.properties
index 3cd2a88..c5c221f 100644
--- a/integration-tests/main/src/main/resources/application.properties
+++ b/integration-tests/main/src/main/resources/application.properties
@@ -28,11 +28,6 @@ camel.rest.port = 9876
 camel.resilience4j.sliding-window-size = 1234
 
 #
-# Timer
-#
-camel.component.timer.basic-property-binding = true
-
-#
 # Main
 #
 camel.main.auto-configuration-log-summary = false
diff --git a/integration-tests/main/src/test/java/org/apache/camel/quarkus/main/CoreMainTest.java b/integration-tests/main/src/test/java/org/apache/camel/quarkus/main/CoreMainTest.java
index 053d29f..5ab20b9 100644
--- a/integration-tests/main/src/test/java/org/apache/camel/quarkus/main/CoreMainTest.java
+++ b/integration-tests/main/src/test/java/org/apache/camel/quarkus/main/CoreMainTest.java
@@ -51,16 +51,10 @@ public class CoreMainTest {
     @Test
     public void testProperties() {
         RestAssured.when().get("/test/property/camel.context.name").then().body(is("quarkus-camel-example"));
-        RestAssured.when().get("/test/property/camel.component.timer.basic-property-binding").then().body(is("true"));
         RestAssured.when().get("/test/property/the.message").then().body(is("test"));
     }
 
     @Test
-    public void timerPropertyPropagated() {
-        RestAssured.when().get("/test/timer/property-binding").then().body(is("true"));
-    }
-
-    @Test
     public void testSetCamelContextName() {
         Response response = RestAssured.get("/test/context/name").andReturn();
 
diff --git a/integration-tests/saga/src/main/java/org/apache/camel/quarkus/component/saga/it/SagaRoute.java b/integration-tests/saga/src/main/java/org/apache/camel/quarkus/component/saga/it/SagaRoute.java
index 32dc3cb..6196340 100644
--- a/integration-tests/saga/src/main/java/org/apache/camel/quarkus/component/saga/it/SagaRoute.java
+++ b/integration-tests/saga/src/main/java/org/apache/camel/quarkus/component/saga/it/SagaRoute.java
@@ -21,9 +21,9 @@ import javax.inject.Inject;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.impl.saga.InMemorySagaService;
 import org.apache.camel.model.SagaPropagation;
 import org.apache.camel.saga.CamelSagaService;
+import org.apache.camel.saga.InMemorySagaService;
 
 @ApplicationScoped
 public class SagaRoute extends RouteBuilder {
diff --git a/pom.xml b/pom.xml
index fa3c21e..1e0c8cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-dependencies</artifactId>
-        <version>3.6.0</version>
+        <version>3.7.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.camel.quarkus</groupId>
@@ -44,7 +44,7 @@
         <avro-ipc-version>1.10.0</avro-ipc-version>
         <awssdk1-swf-libs.version>1.11.22</awssdk1-swf-libs.version>
         <bouncycastle.version>${bouncycastle-version}</bouncycastle.version><!-- keep in sync with Camel -->
-        <camel.version>3.6.0</camel.version>
+        <camel.version>3.7.0-SNAPSHOT</camel.version>
         <commons-beanutils.version>${commons-beanutils-version}</commons-beanutils.version><!-- keep in sync with Camel -->
         <commons-cli.version>1.4</commons-cli.version><!-- keep in sync with Quarkus, via quarkus-bootstrap-core -->
         <commons-collections.version>3.2.2</commons-collections.version><!-- used by hbase, should be pretty stable as commons-collections are not developed actively anymore -->
@@ -69,6 +69,7 @@
         <jackson-asl.version>1.9.13</jackson-asl.version><!-- Mess in the transitive dependencies of spark and hbase-testing-util -->
         <java.xml.ws.version>2.3.1</java.xml.ws.version>
         <jcodings.version>1.0.55</jcodings.version><!-- used by hbase -->
+        <joni.version>2.1.31</joni.version><!-- used by json-validator -->
         <jaxen.version>1.2.0</jaxen.version>
         <javassist.version>3.22.0-CR2</javassist.version><!-- debezium -->
         <jersey-sun.version>1.19.4</jersey-sun.version><!-- Spark -->
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index b39fb92..bec05c2 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -656,6 +656,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
+                <artifactId>camel-core-processor</artifactId>
+                <version>${camel.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
                 <artifactId>camel-couchbase</artifactId>
                 <version>${camel.version}</version>
             </dependency>
@@ -5668,6 +5673,11 @@
                 <version>${jcodings.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.jruby.joni</groupId>
+                <artifactId>joni</artifactId>
+                <version>${joni.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.kie.soup</groupId>
                 <artifactId>kie-soup-commons</artifactId>
                 <version>${optaplanner.version}</version>


[camel-quarkus] 06/06: CSimple language support #2036

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

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

commit 0b4216ac79fdf0e96fa8c8ee9e70314e817cb61d
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Thu Dec 3 12:45:19 2020 +0100

    CSimple language support #2036
---
 .../ROOT/pages/reference/extensions/core.adoc      |   6 +
 .../partials/reference/components/vertx-kafka.adoc |   1 +
 extensions-core/core/deployment/pom.xml            |  16 +
 .../CSimpleRouteDefinitionProcessor.java           | 354 +++++++++++++++++++++
 .../LanguageExpressionContentHandler.java          | 122 +++++++
 .../spi/CSimpleExpressionSourceBuildItem.java      |  58 ++++
 .../spi/CompiledCSimpleExpressionBuildItem.java    |  57 ++++
 .../core/runtime/src/main/adoc/limitations.adoc    |  17 +
 .../quarkus/core/CSimpleLanguageRecorder.java      |  24 +-
 .../org/apache/camel/quarkus/core/CamelConfig.java |  18 ++
 .../main/deployment/CSimpleXmlProcessor.java       | 127 ++++++++
 integration-tests/core/pom.xml                     |  42 +++
 .../apache/camel/quarkus/core/CoreResource.java    |  14 +
 .../org/apache/camel/quarkus/core/CoreRoutes.java  |   3 +
 .../org/apache/camel/quarkus/core/CoreTest.java    |  12 +
 .../camel/quarkus/main/CoreMainXmlIoResource.java  |   8 +
 .../src/main/resources/routes/my-routes.xml        |   7 +
 .../camel/quarkus/main/CoreMainXmlIoTest.java      |  13 +-
 18 files changed, 890 insertions(+), 9 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/core.adoc b/docs/modules/ROOT/pages/reference/extensions/core.adoc
index cd8e0a5..381b7b6 100644
--- a/docs/modules/ROOT/pages/reference/extensions/core.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/core.adoc
@@ -160,6 +160,12 @@ A comma separated list of Ant-path style patterns to match class names that shou
  For this option to work properly, the artifacts containing the selected classes must either contain a Jandex index (`META-INF/jandex.idx`) or they must be registered for indexing using the `quarkus.index-dependency.++*++` family of options in `application.properties` - e.g. quarkus.index-dependency.my-dep.group-id = org.my-group quarkus.index-dependency.my-dep.artifact-id = my-artifact  where `my-dep` is a label of your choice to tell Quarkus that `org.my-group` and with `my-artifact` b [...]
 | `string`
 | 
+
+|icon:lock[title=Fixed at build time] [[quarkus.camel.csimple.on-build-time-analysis-failure]]`link:#quarkus.camel.csimple.on-build-time-analysis-failure[quarkus.camel.csimple.on-build-time-analysis-failure]`
+
+What to do if it is not possible to extract CSimple expressions from a route definition at build time.
+| `org.apache.camel.quarkus.core.CamelConfig.FailureRemedy`
+| `warn`
 |===
 
 [.configuration-legend]
diff --git a/docs/modules/ROOT/partials/reference/components/vertx-kafka.adoc b/docs/modules/ROOT/partials/reference/components/vertx-kafka.adoc
new file mode 100644
index 0000000..a509c1d
--- /dev/null
+++ b/docs/modules/ROOT/partials/reference/components/vertx-kafka.adoc
@@ -0,0 +1 @@
+// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page
diff --git a/extensions-core/core/deployment/pom.xml b/extensions-core/core/deployment/pom.xml
index 37b0c2d..bf0822b 100644
--- a/extensions-core/core/deployment/pom.xml
+++ b/extensions-core/core/deployment/pom.xml
@@ -49,6 +49,22 @@
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
 
+        <!-- JAXB is needed for the build time routes introspection -->
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-runtime</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>jakarta.xml.bind</groupId>
+                    <artifactId>jakarta.xml.bind-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.xml.bind</groupId>
+            <artifactId>jboss-jaxb-api_2.3_spec</artifactId>
+        </dependency>
+
         <!-- test dependencies -->
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CSimpleRouteDefinitionProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CSimpleRouteDefinitionProcessor.java
new file mode 100644
index 0000000..c9878ab
--- /dev/null
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CSimpleRouteDefinitionProcessor.java
@@ -0,0 +1,354 @@
+/*
+ * 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.quarkus.core.deployment;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Marshaller.Listener;
+
+import io.quarkus.bootstrap.classloading.ClassPathElement;
+import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
+import io.quarkus.deployment.dev.CompilationProvider;
+import io.quarkus.deployment.dev.CompilationProvider.Context;
+import io.quarkus.deployment.dev.JavaCompilationProvider;
+import io.quarkus.deployment.recording.RecorderContext;
+import io.quarkus.runtime.RuntimeValue;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.NamedNode;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.language.csimple.CSimpleCodeGenerator;
+import org.apache.camel.language.csimple.CSimpleGeneratedCode;
+import org.apache.camel.language.csimple.CSimpleHelper;
+import org.apache.camel.language.csimple.CSimpleLanguage;
+import org.apache.camel.language.csimple.CSimpleLanguage.Builder;
+import org.apache.camel.model.Constants;
+import org.apache.camel.model.ExpressionNode;
+import org.apache.camel.quarkus.core.CSimpleLanguageRecorder;
+import org.apache.camel.quarkus.core.CamelConfig;
+import org.apache.camel.quarkus.core.CamelConfig.FailureRemedy;
+import org.apache.camel.quarkus.core.deployment.spi.CSimpleExpressionSourceBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem;
+import org.apache.camel.util.PropertiesHelper;
+import org.jboss.logging.Logger;
+
+class CSimpleRouteDefinitionProcessor {
+    private static final Logger LOG = Logger.getLogger(CSimpleRouteDefinitionProcessor.class);
+    static final String CLASS_EXT = ".class";
+
+    @BuildStep
+    void collectCSimpleExpresions(
+            CamelConfig config,
+            List<CamelRoutesBuilderClassBuildItem> routesBuilderClasses,
+            BuildProducer<CSimpleExpressionSourceBuildItem> csimpleExpressions)
+            throws IOException, ClassNotFoundException, URISyntaxException, JAXBException {
+
+        if (!routesBuilderClasses.isEmpty()) {
+            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            if (!(loader instanceof QuarkusClassLoader)) {
+                throw new IllegalStateException(
+                        QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
+            }
+
+            final ExpressionCollector collector = new ExpressionCollector(loader);
+
+            final CamelContext ctx = new DefaultCamelContext();
+            for (CamelRoutesBuilderClassBuildItem routesBuilderClass : routesBuilderClasses) {
+                final String className = routesBuilderClass.getDotName().toString();
+                final Class<?> cl = loader.loadClass(className);
+
+                if (!RouteBuilder.class.isAssignableFrom(cl)) {
+                    LOG.warnf("CSimple language expressions ocurring in %s won't be compiled at build time", cl);
+                } else {
+                    try {
+                        final RouteBuilder rb = (RouteBuilder) cl.newInstance();
+                        rb.setContext(ctx);
+                        try {
+                            rb.configure();
+                            collector.collect(
+                                    "csimple",
+                                    (script, isPredicate) -> csimpleExpressions.produce(
+                                            new CSimpleExpressionSourceBuildItem(
+                                                    script,
+                                                    isPredicate,
+                                                    className)),
+                                    rb.getRouteCollection(),
+                                    rb.getRestCollection());
+
+                        } catch (Exception e) {
+                            switch (config.csimple.onBuildTimeAnalysisFailure) {
+                            case fail:
+                                throw new RuntimeException(
+                                        "Could not extract CSimple expressions from " + className
+                                                + ". You may want to set quarkus.camel.csimple.on-build-time-analysis-failure to warn or ignore if you do not use CSimple language in your routes",
+                                        e);
+                            case warn:
+                                LOG.warnf(e,
+                                        "Could not extract CSimple language expressions from the route definition %s in class %s.",
+                                        rb, cl);
+                                break;
+                            case ignore:
+                                LOG.debugf(e,
+                                        "Could not extract CSimple language expressions from the route definition %s in class %s",
+                                        rb, cl);
+                                break;
+                            default:
+                                throw new IllegalStateException("Unexpected " + FailureRemedy.class.getSimpleName() + ": "
+                                        + config.csimple.onBuildTimeAnalysisFailure);
+                            }
+                        }
+
+                    } catch (InstantiationException | IllegalAccessException e) {
+                        throw new RuntimeException("Could not instantiate " + className, e);
+                    }
+                }
+            }
+        }
+    }
+
+    @BuildStep
+    void compileCSimpleExpresions(
+            List<CSimpleExpressionSourceBuildItem> expressionSources,
+            BuildProducer<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpression,
+            BuildProducer<GeneratedClassBuildItem> generatedClasses) throws IOException {
+
+        if (!expressionSources.isEmpty()) {
+            final Set<String> imports = new TreeSet<>();
+            final Map<String, String> aliases = new LinkedHashMap<>();
+            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            if (!(loader instanceof QuarkusClassLoader)) {
+                throw new IllegalStateException(
+                        QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
+            }
+            final QuarkusClassLoader quarkusClassLoader = (QuarkusClassLoader) loader;
+            readConfig(imports, aliases, loader);
+            final CSimpleCodeGenerator generator = new CSimpleCodeGenerator();
+            generator.setAliases(aliases);
+            generator.setImports(imports);
+
+            final Path projectDir = Paths.get(".").toAbsolutePath().normalize();
+            final Path csimpleGeneratedSourceDir = projectDir.resolve("target/generated/csimple");
+            Files.createDirectories(csimpleGeneratedSourceDir);
+
+            final Set<File> filesToCompile = new LinkedHashSet<>();
+
+            /* We do not want to compile the same source twice, so we store here what we have compiled already */
+            final Map<Boolean, Set<String>> compiledExpressions = new HashMap<>();
+            compiledExpressions.put(true, new HashSet<>());
+            compiledExpressions.put(false, new HashSet<>());
+
+            /* Generate Java classes for the language expressions */
+            for (CSimpleExpressionSourceBuildItem expr : expressionSources) {
+                final boolean predicate = expr.isPredicate();
+                final String script = expr.getSourceCode();
+                if (!compiledExpressions.get(predicate).contains(script)) {
+                    final CSimpleGeneratedCode code = predicate
+                            ? generator.generatePredicate(expr.getClassNameBase(), script)
+                            : generator.generateExpression(expr.getClassNameBase(), script);
+
+                    compiledCSimpleExpression
+                            .produce(new CompiledCSimpleExpressionBuildItem(code.getCode(), predicate, code.getFqn()));
+
+                    final Path javaCsimpleFile = csimpleGeneratedSourceDir
+                            .resolve(code.getFqn().replace('.', '/') + ".java");
+                    Files.createDirectories(javaCsimpleFile.getParent());
+                    Files.write(javaCsimpleFile, code.getCode().getBytes(StandardCharsets.UTF_8));
+                    filesToCompile.add(javaCsimpleFile.toFile());
+                    compiledExpressions.get(predicate).add(script);
+                }
+            }
+
+            final Path csimpleClassesDir = projectDir.resolve("target/csimple-classes");
+            Files.createDirectories(csimpleClassesDir);
+
+            /* Compile the generated sources */
+            try (JavaCompilationProvider compiler = new JavaCompilationProvider()) {
+                final Context context = compilationContext(projectDir, csimpleClassesDir, quarkusClassLoader);
+                compiler.compile(filesToCompile, context);
+            }
+
+            /* Register the compiled classes via Quarkus GeneratedClassBuildItem */
+            try (Stream<Path> classFiles = Files.walk(csimpleClassesDir)) {
+                classFiles
+                        .filter(Files::isRegularFile)
+                        .filter(p -> p.getFileName().toString().endsWith(CLASS_EXT))
+                        .forEach(p -> {
+                            final Path relPath = csimpleClassesDir.relativize(p);
+                            String className = relPath.toString();
+                            className = className.substring(0, className.length() - CLASS_EXT.length());
+                            try {
+                                final GeneratedClassBuildItem item = new GeneratedClassBuildItem(true, className,
+                                        Files.readAllBytes(p));
+                                generatedClasses.produce(item);
+                            } catch (IOException e) {
+                                throw new RuntimeException("Could not read " + p);
+                            }
+                        });
+            }
+
+        }
+    }
+
+    @Record(ExecutionTime.STATIC_INIT)
+    @BuildStep
+    CamelBeanBuildItem configureCSimpleLanguage(
+            RecorderContext recorderContext,
+            CSimpleLanguageRecorder recorder,
+            CamelContextBuildItem camelContext,
+            List<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpressions) {
+
+        final RuntimeValue<Builder> builder = recorder.csimpleLanguageBuilder();
+        for (CompiledCSimpleExpressionBuildItem expr : compiledCSimpleExpressions) {
+            recorder.addExpression(builder, recorderContext.newInstance(expr.getClassName()));
+        }
+
+        final RuntimeValue<?> csimpleLanguage = recorder.buildCSimpleLanguage(builder);
+        return new CamelBeanBuildItem("csimple", CSimpleLanguage.class.getName(), csimpleLanguage);
+    }
+
+    static void readConfig(Set<String> imports, Map<String, String> aliases, ClassLoader cl) throws IOException {
+        Enumeration<URL> confiUrls = cl.getResources("camel-csimple.properties");
+        while (confiUrls.hasMoreElements()) {
+            final URL configUrl = confiUrls.nextElement();
+            try (BufferedReader r = new BufferedReader(new InputStreamReader(configUrl.openStream(), StandardCharsets.UTF_8))) {
+                String line = null;
+                while ((line = r.readLine()) != null) {
+                    line = line.trim();
+                    // skip comments
+                    if (line.startsWith("#")) {
+                        continue;
+                    }
+                    // imports
+                    if (line.startsWith("import ")) {
+                        imports.add(line);
+                        continue;
+                    }
+                    // aliases as key=value
+                    final int eqPos = line.indexOf('=');
+                    final String key = line.substring(0, eqPos).trim();
+                    final String value = line.substring(eqPos + 1).trim();
+                    aliases.put(key, value);
+
+                }
+            } catch (IOException e) {
+                throw new RuntimeException("Could not read from " + configUrl);
+            }
+        }
+    }
+
+    private Context compilationContext(final Path projectDir, final Path csimpleClassesDir,
+            QuarkusClassLoader quarkusClassLoader) {
+        Set<File> classPathElements = Stream.of(CSimpleHelper.class, Exchange.class, PropertiesHelper.class)
+                .map(clazz -> clazz.getName().replace('.', '/') + CLASS_EXT)
+                .flatMap(className -> (Stream<ClassPathElement>) quarkusClassLoader.getElementsWithResource(className).stream())
+                .map(cpe -> cpe.getRoot())
+                .filter(p -> p != null)
+                .map(Path::toFile)
+                .collect(Collectors.toSet());
+
+        return new CompilationProvider.Context(
+                "csimple-project",
+                classPathElements,
+                projectDir.toFile(),
+                projectDir.resolve("src/main/java").toFile(),
+                csimpleClassesDir.toFile(),
+                StandardCharsets.UTF_8.name(),
+                Collections.emptyList(),
+                "1.8",
+                "1.8",
+                Collections.emptyList(),
+                Collections.emptyList());
+    }
+
+    /**
+     * Collects expressions of a given language.
+     */
+    static class ExpressionCollector {
+        private final JAXBContext jaxbContext;
+        private final Marshaller marshaler;
+
+        ExpressionCollector(ClassLoader loader) {
+            try {
+                jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, loader);
+                Marshaller m = jaxbContext.createMarshaller();
+                m.setListener(new RouteDefinitionNormalizer());
+                marshaler = m;
+            } catch (JAXBException e) {
+                throw new RuntimeException("Could not creat a JAXB marshaler", e);
+            }
+        }
+
+        public void collect(String languageName, BiConsumer<String, Boolean> expressionConsumer, NamedNode... nodes) {
+            final LanguageExpressionContentHandler handler = new LanguageExpressionContentHandler(languageName,
+                    expressionConsumer);
+            for (NamedNode node : nodes) {
+                try {
+                    marshaler.marshal(node, handler);
+                } catch (JAXBException e) {
+                    throw new RuntimeException("Could not collect '" + languageName + "' expressions from node " + node, e);
+                }
+            }
+        }
+
+        /**
+         * Inlines all fancy expression builders so that JAXB can serialize the model properly.
+         */
+        private static class RouteDefinitionNormalizer extends Listener {
+            public void beforeMarshal(Object source) {
+                if (source instanceof ExpressionNode) {
+                    ((ExpressionNode) source).preCreateProcessor();
+                }
+            }
+        }
+
+    }
+
+}
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/LanguageExpressionContentHandler.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/LanguageExpressionContentHandler.java
new file mode 100644
index 0000000..51d6abb
--- /dev/null
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/LanguageExpressionContentHandler.java
@@ -0,0 +1,122 @@
+/*
+ * 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.quarkus.core.deployment;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class LanguageExpressionContentHandler extends DefaultHandler {
+
+    private final String languageName;
+
+    private final BiConsumer<String, Boolean> expressionConsumer;
+    private boolean inExpression = false;
+    private final StringBuilder expressionBuilder = new StringBuilder();
+    private final Deque<Map.Entry<String, Attributes>> path = new ArrayDeque<>();
+
+    public LanguageExpressionContentHandler(String languageName, BiConsumer<String, Boolean> expressionConsumer) {
+        super();
+        this.languageName = languageName;
+        this.expressionConsumer = expressionConsumer;
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes atts)
+            throws SAXException {
+        if (inExpression) {
+            throw new IllegalStateException("Unexpected element '" + localName + "' under '" + languageName
+                    + "'; only text content is expected");
+        }
+        if (languageName.equals(localName)) {
+            inExpression = true;
+        } else {
+            path.push(new SimpleImmutableEntry<String, Attributes>(localName, atts));
+        }
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (languageName.equals(localName)) {
+            final String expressionText = expressionBuilder.toString();
+            final boolean predicate = isPredicate();
+            expressionConsumer.accept(expressionText, predicate);
+            expressionBuilder.setLength(0);
+            inExpression = false;
+        } else {
+            path.pop();
+        }
+    }
+
+    private boolean isPredicate() {
+        Entry<String, Attributes> parent = path.peek();
+        if (parent != null) {
+            return hasSimplePredicateChild(parent.getKey(), attributeName -> {
+                final Attributes attribs = parent.getValue();
+                if (attribs != null) {
+                    return attribs.getValue(attributeName);
+                }
+                return null;
+            });
+        }
+        return false;
+    }
+
+    /**
+     * Inspired by {@link org.apache.camel.parser.XmlRouteParser#isSimplePredicate(Node)}.
+     *
+     * @param  name
+     * @param  getAttributeFunction
+     * @return
+     */
+    public static boolean hasSimplePredicateChild(String name, Function<String, String> getAttributeFunction) {
+
+        if (name == null) {
+            return false;
+        }
+        if (name.equals("completionPredicate") || name.equals("completion")) {
+            return true;
+        }
+        if (name.equals("onWhen") || name.equals("when") || name.equals("handled") || name.equals("continued")) {
+            return true;
+        }
+        if (name.equals("retryWhile") || name.equals("filter") || name.equals("validate")) {
+            return true;
+        }
+        // special for loop
+        if (name.equals("loop") && "true".equalsIgnoreCase(getAttributeFunction.apply("doWhile"))) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        if (inExpression) {
+            expressionBuilder.append(ch, start, length);
+        }
+    }
+
+}
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CSimpleExpressionSourceBuildItem.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CSimpleExpressionSourceBuildItem.java
new file mode 100644
index 0000000..1547e6f
--- /dev/null
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CSimpleExpressionSourceBuildItem.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quarkus.core.deployment.spi;
+
+import io.quarkus.builder.item.MultiBuildItem;
+
+/**
+ * A {@link MultiBuildItem} bearing info about a CSimple language expression that needs to get compiled.
+ */
+public final class CSimpleExpressionSourceBuildItem extends MultiBuildItem {
+
+    private final String sourceCode;
+    private final String classNameBase;
+    private final boolean predicate;
+
+    public CSimpleExpressionSourceBuildItem(String sourceCode, boolean predicate, String classNameBase) {
+        this.sourceCode = sourceCode;
+        this.predicate = predicate;
+        this.classNameBase = classNameBase;
+    }
+
+    /**
+     * @return the expression source code to compile
+     */
+    public String getSourceCode() {
+        return sourceCode;
+    }
+
+    /**
+     * @return a fully qualified class name that the compiler may use as a base for the name of the class into which it
+     *         compiles the source code returned by {@link #getSourceCode()}
+     */
+    public String getClassNameBase() {
+        return classNameBase;
+    }
+
+    /**
+     * @return {@code true} if the expression is a predicate; {@code false} otherwise
+     */
+    public boolean isPredicate() {
+        return predicate;
+    }
+
+}
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java
new file mode 100644
index 0000000..e81139c
--- /dev/null
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.quarkus.core.deployment.spi;
+
+import io.quarkus.builder.item.MultiBuildItem;
+
+/**
+ * A {@link MultiBuildItem} bearing info about a compiled CSimple language expression.
+ */
+public final class CompiledCSimpleExpressionBuildItem extends MultiBuildItem {
+
+    private final String sourceCode;
+    private final String className;
+    private final boolean predicate;
+
+    public CompiledCSimpleExpressionBuildItem(String sourceCode, boolean predicate, String className) {
+        this.sourceCode = sourceCode;
+        this.predicate = predicate;
+        this.className = className;
+    }
+
+    /**
+     * @return the source code out which the class returned by {@link #getClassName()} was compiled
+     */
+    public String getSourceCode() {
+        return sourceCode;
+    }
+
+    /**
+     * @return a fully qualified class name compiled from the source code returned by {@link #getSourceCode()}
+     */
+    public String getClassName() {
+        return className;
+    }
+
+    /**
+     * @return {@code true} if the expression is a predicate; {@code false} otherwise
+     */
+    public boolean isPredicate() {
+        return predicate;
+    }
+
+}
diff --git a/extensions-core/core/runtime/src/main/adoc/limitations.adoc b/extensions-core/core/runtime/src/main/adoc/limitations.adoc
new file mode 100644
index 0000000..9697d1c
--- /dev/null
+++ b/extensions-core/core/runtime/src/main/adoc/limitations.adoc
@@ -0,0 +1,17 @@
+=== CSimple language
+
+CSimple language is supported only in
+
+* XML DSL
+* Java DSL when implemented in a class extending `org.apache.camel.builder.RouteBuilder`
+
+The compilation of CSimple scripts happens at build time. To extract the scripts from the route definitions, these need
+to be assembled at build time. This may fail if the given route requires some data that is only available at runtime.
+You can use the `quarkus.camel.csimple.on-build-time-analysis-failure` configuration parameter to decide
+what should happen in such cases. The possible values are `warn` (default), `fail` or `ignore`.
+
+[WARNING]
+====
+CSimple language will not work on Camel Quarkus if used in a `org.apache.camel.builder.LambdaRouteBuilder`
+====
+
diff --git a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CSimpleLanguageRecorder.java
similarity index 52%
copy from integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java
copy to extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CSimpleLanguageRecorder.java
index 4aa1678..d0237d7 100644
--- a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CSimpleLanguageRecorder.java
@@ -16,17 +16,25 @@
  */
 package org.apache.camel.quarkus.core;
 
-import org.apache.camel.builder.RouteBuilder;
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.language.csimple.CSimpleExpression;
+import org.apache.camel.language.csimple.CSimpleLanguage;
+import org.apache.camel.language.csimple.CSimpleLanguage.Builder;
 
-public class CoreRoutes extends RouteBuilder {
+@Recorder
+public class CSimpleLanguageRecorder {
 
-    @Override
-    public void configure() {
-        from("timer:keep-alive")
-                .routeId("timer")
-                .setBody().constant("I'm alive !")
-                .to("log:keep-alive");
+    public RuntimeValue<CSimpleLanguage.Builder> csimpleLanguageBuilder() {
+        return new RuntimeValue<>(CSimpleLanguage.builder());
+    }
+
+    public void addExpression(RuntimeValue<Builder> builder, RuntimeValue<CSimpleExpression> expression) {
+        builder.getValue().expression(expression.getValue());
+    }
 
+    public RuntimeValue<?> buildCSimpleLanguage(RuntimeValue<Builder> builder) {
+        return new RuntimeValue<>(builder.getValue().build());
     }
 
 }
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
index 78573ef..e856007 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
@@ -26,6 +26,10 @@ import io.quarkus.runtime.annotations.ConfigRoot;
 
 @ConfigRoot(name = "camel", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
 public class CamelConfig {
+    public enum FailureRemedy {
+        fail, warn, ignore
+    }
+
     /**
      * Build time configuration options for {@link CamelRuntime} bootstrap.
      */
@@ -56,6 +60,12 @@ public class CamelConfig {
     @ConfigItem(name = "native")
     public NativeConfig native_;
 
+    /**
+     * Build time configuration options for the Camel CSimple language.
+     */
+    @ConfigItem
+    public CSimpleConfig csimple;
+
     @ConfigGroup
     public static class BootstrapConfig {
         /**
@@ -329,4 +339,12 @@ public class CamelConfig {
         @ConfigItem(defaultValue = "true")
         public boolean models;
     }
+
+    @ConfigGroup
+    public static class CSimpleConfig {
+
+        /** What to do if it is not possible to extract CSimple expressions from a route definition at build time. */
+        @ConfigItem(defaultValue = "warn")
+        public FailureRemedy onBuildTimeAnalysisFailure;
+    }
 }
diff --git a/extensions-core/main/deployment/src/main/java/org/apache/camel/quarkus/main/deployment/CSimpleXmlProcessor.java b/extensions-core/main/deployment/src/main/java/org/apache/camel/quarkus/main/deployment/CSimpleXmlProcessor.java
new file mode 100644
index 0000000..c227733
--- /dev/null
+++ b/extensions-core/main/deployment/src/main/java/org/apache/camel/quarkus/main/deployment/CSimpleXmlProcessor.java
@@ -0,0 +1,127 @@
+/*
+ * 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.quarkus.main.deployment;
+
+import java.io.Closeable;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.DefaultPackageScanResourceResolver;
+import org.apache.camel.quarkus.core.CamelConfig;
+import org.apache.camel.quarkus.core.deployment.LanguageExpressionContentHandler;
+import org.apache.camel.quarkus.core.deployment.spi.CSimpleExpressionSourceBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem;
+import org.apache.camel.quarkus.core.deployment.util.CamelSupport;
+import org.jboss.logging.Logger;
+
+public class CSimpleXmlProcessor {
+
+    private static final Logger LOG = Logger.getLogger(CSimpleXmlProcessor.class);
+
+    @BuildStep
+    void collectCSimpleExpresions(
+            CamelConfig config,
+            List<CamelRoutesBuilderClassBuildItem> routesBuilderClasses,
+            BuildProducer<CSimpleExpressionSourceBuildItem> csimpleExpressions)
+            throws ParserConfigurationException, SAXException, IOException {
+
+        final List<String> locations = Stream.of("camel.main.xml-routes", "camel.main.xml-rests")
+                .map(prop -> CamelSupport.getOptionalConfigValue(prop, String[].class, new String[0]))
+                .flatMap(Stream::of)
+                .collect(Collectors.toList());
+
+        try (DefaultPackageScanResourceResolver resolver = new DefaultPackageScanResourceResolver()) {
+            resolver.setCamelContext(new DefaultCamelContext());
+            final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+            saxParserFactory.setNamespaceAware(true);
+            SAXParser saxParser = saxParserFactory.newSAXParser();
+            for (String part : locations) {
+                try {
+                    try (CloseableCollection<InputStream> set = new CloseableCollection<InputStream>(
+                            resolver.findResources(part))) {
+                        for (InputStream is : set) {
+                            LOG.debugf("Found XML routes from location: %s", part);
+                            try {
+                                saxParser.parse(
+                                        is,
+                                        new LanguageExpressionContentHandler(
+                                                "csimple",
+                                                (script, isPredicate) -> csimpleExpressions.produce(
+                                                        new CSimpleExpressionSourceBuildItem(
+                                                                script,
+                                                                isPredicate,
+                                                                "org.apache.camel.language.csimple.XmlRouteBuilder"))));
+                            } finally {
+                                if (is != null) {
+                                    is.close();
+                                }
+                            }
+                        }
+                    }
+                } catch (FileNotFoundException e) {
+                    LOG.debugf("No XML routes found in %s. Skipping XML routes detection.", part);
+                } catch (Exception e) {
+                    throw new RuntimeException("Could not analyze CSimple expressions in " + part, e);
+                }
+            }
+        }
+    }
+
+    static class CloseableCollection<E extends Closeable> implements Closeable, Iterable<E> {
+        private final Collection<E> delegate;
+
+        public CloseableCollection(Collection<E> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void close() throws IOException {
+            List<Exception> exceptions = new ArrayList<>();
+            for (Closeable closeable : delegate) {
+                try {
+                    closeable.close();
+                } catch (Exception e) {
+                    exceptions.add(e);
+                }
+            }
+            if (!exceptions.isEmpty()) {
+                throw new IOException("Could not close a resource", exceptions.get(0));
+            }
+        }
+
+        @Override
+        public Iterator<E> iterator() {
+            return delegate.iterator();
+        }
+    }
+}
diff --git a/integration-tests/core/pom.xml b/integration-tests/core/pom.xml
index 13c761a..9c77a65 100644
--- a/integration-tests/core/pom.xml
+++ b/integration-tests/core/pom.xml
@@ -119,6 +119,48 @@
 
     </dependencies>
 
+    <build>
+        <plugins>
+<!--             <plugin>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-csimple-maven-plugin</artifactId>
+                <version>${camel.version}</version>
+                <executions>
+                    <execution>
+                        <id>generate</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                            <goal>add-resource</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>src/generated/java</source>
+                            </sources>
+                            <resources>
+                                <resource>
+                                    <directory>src/generated/resources</directory>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin> -->
+        </plugins>
+    </build>
+
 
     <profiles>
         <profile>
diff --git a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
index 8587ef5..60e4c2f 100644
--- a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
+++ b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreResource.java
@@ -28,7 +28,9 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.json.Json;
 import javax.json.JsonObject;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -39,6 +41,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.ProducerTemplate;
 import org.apache.camel.Route;
 import org.apache.camel.builder.LambdaRouteBuilder;
 import org.apache.camel.builder.TemplatedRouteBuilder;
@@ -59,6 +62,9 @@ public class CoreResource {
     @Inject
     CamelContext context;
 
+    @Inject
+    ProducerTemplate producerTemplate;
+
     @Path("/registry/log/exchange-formatter")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
@@ -261,4 +267,12 @@ public class CoreResource {
     public boolean headersMapFactory() {
         return context.adapt(ExtendedCamelContext.class).getHeadersMapFactory() instanceof DefaultHeadersMapFactory;
     }
+
+    @Path("/csimple-hello")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String csimpleHello(String body) {
+        return producerTemplate.requestBody("direct:csimple-hello", body, String.class);
+    }
 }
diff --git a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java
index 4aa1678..5956f38 100644
--- a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java
+++ b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CoreRoutes.java
@@ -27,6 +27,9 @@ public class CoreRoutes extends RouteBuilder {
                 .setBody().constant("I'm alive !")
                 .to("log:keep-alive");
 
+        from("direct:csimple-hello")
+                .setBody().csimple("Hello ${body}");
+
     }
 
 }
diff --git a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
index 0ba16c9..a96f2fe 100644
--- a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
+++ b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CoreTest.java
@@ -21,6 +21,7 @@ import java.net.HttpURLConnection;
 
 import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
 import io.restassured.response.Response;
 import org.apache.camel.support.DefaultLRUCacheFactory;
 import org.junit.jupiter.api.Test;
@@ -123,4 +124,15 @@ public class CoreTest {
     void testDefaultHeadersMapFactoryConfigured() {
         RestAssured.when().get("/test/headersmap-factory").then().body(is("true"));
     }
+
+    @Test
+    public void csimpleHello() {
+        RestAssured.given()
+                .body("Joe")
+                .contentType(ContentType.TEXT)
+                .post("/test/csimple-hello")
+                .then()
+                .body(is("Hello Joe"));
+    }
+
 }
diff --git a/integration-tests/main-xml-io/src/main/java/org/apache/camel/quarkus/main/CoreMainXmlIoResource.java b/integration-tests/main-xml-io/src/main/java/org/apache/camel/quarkus/main/CoreMainXmlIoResource.java
index d69e170..fb3ce7d 100644
--- a/integration-tests/main-xml-io/src/main/java/org/apache/camel/quarkus/main/CoreMainXmlIoResource.java
+++ b/integration-tests/main-xml-io/src/main/java/org/apache/camel/quarkus/main/CoreMainXmlIoResource.java
@@ -90,4 +90,12 @@ public class CoreMainXmlIoResource {
     public String namespaceAware(String body) {
         return template.requestBody("direct:namespace-aware", body, String.class);
     }
+
+    @Path("/csimple-xml-dsl")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String csimpleXmlDsl(String body) {
+        return template.requestBody("direct:csimple-xml-dsl", body, String.class);
+    }
 }
diff --git a/integration-tests/main-xml-io/src/main/resources/routes/my-routes.xml b/integration-tests/main-xml-io/src/main/resources/routes/my-routes.xml
index 48feb17..ae9376a 100644
--- a/integration-tests/main-xml-io/src/main/resources/routes/my-routes.xml
+++ b/integration-tests/main-xml-io/src/main/resources/routes/my-routes.xml
@@ -41,4 +41,11 @@
         </setBody>
     </route>
 
+    <route id="csimple-xml-dsl">
+        <from uri="direct:csimple-xml-dsl"/>
+        <setBody>
+            <csimple>Hi ${body}</csimple>
+        </setBody>
+    </route>
+
 </routes>
\ No newline at end of file
diff --git a/integration-tests/main-xml-io/src/test/java/org/apache/camel/quarkus/main/CoreMainXmlIoTest.java b/integration-tests/main-xml-io/src/test/java/org/apache/camel/quarkus/main/CoreMainXmlIoTest.java
index 617c17b..c8c07c7 100644
--- a/integration-tests/main-xml-io/src/test/java/org/apache/camel/quarkus/main/CoreMainXmlIoTest.java
+++ b/integration-tests/main-xml-io/src/test/java/org/apache/camel/quarkus/main/CoreMainXmlIoTest.java
@@ -30,7 +30,7 @@ import org.apache.camel.xml.in.ModelParserXMLRoutesDefinitionLoader;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.core.Is.is;
+import static org.hamcrest.Matchers.is;
 
 @QuarkusTest
 public class CoreMainXmlIoTest {
@@ -75,4 +75,15 @@ public class CoreMainXmlIoTest {
                 .body(is("bar"));
 
     }
+
+    @Test
+    public void csimpleXml() {
+        RestAssured.given()
+                .body("Joe")
+                .contentType(ContentType.TEXT)
+                .post("/test/csimple-xml-dsl")
+                .then()
+                .body(is("Hi Joe"));
+    }
+
 }


[camel-quarkus] 04/06: BigQuery native support

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

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

commit 1839582579975d37e7e54847b73e5386707beb97
Author: James Netherton <ja...@gmail.com>
AuthorDate: Fri Dec 4 12:08:28 2020 +0000

    BigQuery native support
    
    Fixes #2014
---
 .../reference/extensions/google-bigquery.adoc      |  19 +++-
 .../reference/components/google-bigquery-sql.adoc  |   6 +-
 .../reference/components/google-bigquery.adoc      |   6 +-
 .../google-bigquery/integration-test/pom.xml       |  66 -------------
 .../google/bigquery/it/GoogleBigqueryResource.java |  64 -------------
 extensions-jvm/pom.xml                             |   1 -
 .../google-bigquery/deployment/pom.xml             |   4 +
 .../deployment/GoogleBigqueryProcessor.java        |  26 +++--
 .../google-bigquery/pom.xml                        |   1 -
 .../google-bigquery/runtime/pom.xml                |   6 +-
 .../runtime/src/main/doc/usage.adoc                |   7 ++
 .../GoogleBigQueryConnectionFactoryProducer.java   |  38 ++++----
 .../main/resources/META-INF/quarkus-extension.yaml |   3 +-
 extensions/pom.xml                                 |   1 +
 integration-tests/google-bigquery/README.adoc      |  16 ++++
 .../{jsonb => google-bigquery}/pom.xml             |  64 ++-----------
 .../google/bigquery/it/GoogleBigqueryResource.java | 105 +++++++++++++++++++++
 .../src/main/resources/application.properties      |  19 ++++
 .../google/bigquery/it/GoogleBigqueryIT.java       |  26 +----
 .../google/bigquery/it/GoogleBigqueryTest.java     |  75 +++++++++++++++
 integration-tests/jsonb/pom.xml                    |  13 +++
 integration-tests/pom.xml                          |   1 +
 pom.xml                                            |   2 +-
 poms/bom/pom.xml                                   |  20 ++++
 tooling/scripts/test-categories.yaml               |   1 +
 25 files changed, 333 insertions(+), 257 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/google-bigquery.adoc b/docs/modules/ROOT/pages/reference/extensions/google-bigquery.adoc
index ef9f559..1814f64 100644
--- a/docs/modules/ROOT/pages/reference/extensions/google-bigquery.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/google-bigquery.adoc
@@ -3,15 +3,15 @@
 = Google BigQuery
 :page-aliases: extensions/google-bigquery.adoc
 :cq-artifact-id: camel-quarkus-google-bigquery
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-description: Access Google Cloud BigQuery service using SQL queries or Google Client Services API
 :cq-deprecated: false
 :cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
+:cq-native-since: 1.5.0
 
 [.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.0.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.0.0## [.badge-key]##Native since##[.badge-supported]##1.5.0##
 
 Access Google Cloud BigQuery service using SQL queries or Google Client Services API
 
@@ -33,3 +33,14 @@ Please refer to the above links for usage and configuration details.
 ----
 
 Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+
+== Usage
+
+This extension leverages the Quarkiverse Google Cloud Services extension. The https://github.com/quarkiverse/quarkiverse-google-cloud-services[documentation] describes
+how to configure authentication for Google cloud services.
+
+For convenience, a `GoogleBigQueryConnectionFactory` for use by the `google-bigquery` & `google-bigquery-sql` component is automatically configured.
+
+If you want to read SQL scripts from the classpath with `google-bigquery-sql` in native mode, then you will need to ensure that they are added to the native image via
+the `quarkus.camel.native.resources.include-patterns` configuration property.
+
diff --git a/docs/modules/ROOT/partials/reference/components/google-bigquery-sql.adoc b/docs/modules/ROOT/partials/reference/components/google-bigquery-sql.adoc
index c20fa09..8330f83 100644
--- a/docs/modules/ROOT/partials/reference/components/google-bigquery-sql.adoc
+++ b/docs/modules/ROOT/partials/reference/components/google-bigquery-sql.adoc
@@ -2,11 +2,11 @@
 // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
 :cq-artifact-id: camel-quarkus-google-bigquery
 :cq-artifact-id-base: google-bigquery
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-deprecated: false
 :cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
+:cq-native-since: 1.5.0
 :cq-camel-part-name: google-bigquery-sql
 :cq-camel-part-title: Google BigQuery Standard SQL
 :cq-camel-part-description: Access Google Cloud BigQuery service using SQL queries.
diff --git a/docs/modules/ROOT/partials/reference/components/google-bigquery.adoc b/docs/modules/ROOT/partials/reference/components/google-bigquery.adoc
index 7692d15..fd0ebca 100644
--- a/docs/modules/ROOT/partials/reference/components/google-bigquery.adoc
+++ b/docs/modules/ROOT/partials/reference/components/google-bigquery.adoc
@@ -2,11 +2,11 @@
 // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
 :cq-artifact-id: camel-quarkus-google-bigquery
 :cq-artifact-id-base: google-bigquery
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-deprecated: false
 :cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
+:cq-native-since: 1.5.0
 :cq-camel-part-name: google-bigquery
 :cq-camel-part-title: Google BigQuery
 :cq-camel-part-description: Google BigQuery data warehouse for analytics.
diff --git a/extensions-jvm/google-bigquery/integration-test/pom.xml b/extensions-jvm/google-bigquery/integration-test/pom.xml
deleted file mode 100644
index d3e97bc..0000000
--- a/extensions-jvm/google-bigquery/integration-test/pom.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?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-build-parent-it</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
-        <relativePath>../../../poms/build-parent-it/pom.xml</relativePath>
-    </parent>
-
-    <artifactId>camel-quarkus-google-bigquery-integration-test</artifactId>
-    <name>Camel Quarkus :: Google BigQuery :: Integration Test</name>
-    <description>Integration tests for Camel Quarkus Google BigQuery extension</description>
-
-    <properties>
-        <!-- mvnd, a.k.a. Maven Daemon: https://github.com/mvndaemon/mvnd -->
-        <!-- The following rule tells mvnd to build the listed deployment modules before this module. -->
-        <!-- This is important because mvnd builds modules in parallel by default. The deployment modules are not -->
-        <!-- explicit dependencies of this module in the Maven sense, although they are required by the Quarkus Maven plugin. -->
-        <!-- Please update the rule whenever you change the dependencies of this module by running -->
-        <!--     mvn process-resources -Pformat    from the root directory -->
-        <mvnd.builder.rule>camel-quarkus-google-bigquery-deployment</mvnd.builder.rule>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-google-bigquery</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>
-
-</project>
diff --git a/extensions-jvm/google-bigquery/integration-test/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java b/extensions-jvm/google-bigquery/integration-test/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java
deleted file mode 100644
index 8782cfa..0000000
--- a/extensions-jvm/google-bigquery/integration-test/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.quarkus.component.google.bigquery.it;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-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.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/google-bigquery")
-@ApplicationScoped
-public class GoogleBigqueryResource {
-
-    private static final Logger LOG = Logger.getLogger(GoogleBigqueryResource.class);
-
-    private static final String COMPONENT_GOOGLE_BIGQUERY = "google-bigquery";
-    private static final String COMPONENT_GOOGLE_BIGQUERY_SQL = "google-bigquery-sql";
-    @Inject
-    CamelContext context;
-
-    @Path("/load/component/google-bigquery")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentGoogleBigquery() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_GOOGLE_BIGQUERY) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_GOOGLE_BIGQUERY);
-        return Response.status(500, COMPONENT_GOOGLE_BIGQUERY + " could not be loaded from the Camel context").build();
-    }
-
-    @Path("/load/component/google-bigquery-sql")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentGoogleBigquerySql() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_GOOGLE_BIGQUERY_SQL) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_GOOGLE_BIGQUERY_SQL);
-        return Response.status(500, COMPONENT_GOOGLE_BIGQUERY_SQL + " could not be loaded from the Camel context").build();
-    }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 24750af..b792206 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -71,7 +71,6 @@
         <module>flink</module>
         <module>freemarker</module>
         <module>ganglia</module>
-        <module>google-bigquery</module>
         <module>groovy</module>
         <module>guava-eventbus</module>
         <module>hazelcast</module>
diff --git a/extensions-jvm/google-bigquery/deployment/pom.xml b/extensions/google-bigquery/deployment/pom.xml
similarity index 93%
rename from extensions-jvm/google-bigquery/deployment/pom.xml
rename to extensions/google-bigquery/deployment/pom.xml
index c847479..a1b3b8e 100644
--- a/extensions-jvm/google-bigquery/deployment/pom.xml
+++ b/extensions/google-bigquery/deployment/pom.xml
@@ -31,6 +31,10 @@
 
     <dependencies>
         <dependency>
+            <groupId>io.quarkiverse.googlecloudservices</groupId>
+            <artifactId>quarkus-google-cloud-bigquery-deployment</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
diff --git a/extensions-jvm/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java b/extensions/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java
similarity index 62%
rename from extensions-jvm/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java
rename to extensions/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java
index dda4b60..98bfdb5 100644
--- a/extensions-jvm/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java
+++ b/extensions/google-bigquery/deployment/src/main/java/org/apache/camel/quarkus/component/google/bigquery/deployment/GoogleBigqueryProcessor.java
@@ -16,17 +16,14 @@
  */
 package org.apache.camel.quarkus.component.google.bigquery.deployment;
 
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
 import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
+import org.apache.camel.component.google.bigquery.GoogleBigQueryConnectionFactory;
+import org.apache.camel.quarkus.component.google.bigquery.GoogleBigQueryConnectionFactoryProducer;
 
 class GoogleBigqueryProcessor {
-    private static final Logger LOG = Logger.getLogger(GoogleBigqueryProcessor.class);
-
     private static final String FEATURE = "camel-google-bigquery";
 
     @BuildStep
@@ -34,14 +31,13 @@ class GoogleBigqueryProcessor {
         return new FeatureBuildItem(FEATURE);
     }
 
-    /**
-     * Remove this once this extension starts supporting the native mode.
-     */
-    @BuildStep(onlyIf = NativeBuild.class)
-    @Record(value = ExecutionTime.RUNTIME_INIT)
-    void warnJvmInNative(JvmOnlyRecorder recorder) {
-        JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
-        recorder.warnJvmInNative(FEATURE); // warn at runtime
+    @BuildStep
+    UnremovableBeanBuildItem unremovableBeans() {
+        return UnremovableBeanBuildItem.beanTypes(GoogleBigQueryConnectionFactory.class);
     }
 
+    @BuildStep
+    public AdditionalBeanBuildItem connectionFactoryProducerBean() {
+        return new AdditionalBeanBuildItem(GoogleBigQueryConnectionFactoryProducer.class);
+    }
 }
diff --git a/extensions-jvm/google-bigquery/pom.xml b/extensions/google-bigquery/pom.xml
similarity index 97%
rename from extensions-jvm/google-bigquery/pom.xml
rename to extensions/google-bigquery/pom.xml
index 43738d1..f5f9a80 100644
--- a/extensions-jvm/google-bigquery/pom.xml
+++ b/extensions/google-bigquery/pom.xml
@@ -33,6 +33,5 @@
     <modules>
         <module>deployment</module>
         <module>runtime</module>
-        <module>integration-test</module>
     </modules>
 </project>
diff --git a/extensions-jvm/google-bigquery/runtime/pom.xml b/extensions/google-bigquery/runtime/pom.xml
similarity index 94%
rename from extensions-jvm/google-bigquery/runtime/pom.xml
rename to extensions/google-bigquery/runtime/pom.xml
index 242eae4..bf5989e 100644
--- a/extensions-jvm/google-bigquery/runtime/pom.xml
+++ b/extensions/google-bigquery/runtime/pom.xml
@@ -32,7 +32,7 @@
 
     <properties>
         <camel.quarkus.jvmSince>1.0.0</camel.quarkus.jvmSince>
-        <camel.quarkus.nativeSince>1.0.0</camel.quarkus.nativeSince>
+        <camel.quarkus.nativeSince>1.5.0</camel.quarkus.nativeSince>
     </properties>
 
     <dependencyManagement>
@@ -49,6 +49,10 @@
 
     <dependencies>
         <dependency>
+            <groupId>io.quarkiverse.googlecloudservices</groupId>
+            <artifactId>quarkus-google-cloud-bigquery</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
diff --git a/extensions/google-bigquery/runtime/src/main/doc/usage.adoc b/extensions/google-bigquery/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000..7bced01
--- /dev/null
+++ b/extensions/google-bigquery/runtime/src/main/doc/usage.adoc
@@ -0,0 +1,7 @@
+This extension leverages the Quarkiverse Google Cloud Services extension. The https://github.com/quarkiverse/quarkiverse-google-cloud-services[documentation] describes
+how to configure authentication for Google cloud services.
+
+For convenience, a `GoogleBigQueryConnectionFactory` for use by the `google-bigquery` & `google-bigquery-sql` component is automatically configured.
+
+If you want to read SQL scripts from the classpath with `google-bigquery-sql` in native mode, then you will need to ensure that they are added to the native image via
+the `quarkus.camel.native.resources.include-patterns` configuration property.
diff --git a/extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java b/extensions/google-bigquery/runtime/src/main/java/org/apache/camel/quarkus/component/google/bigquery/GoogleBigQueryConnectionFactoryProducer.java
similarity index 54%
copy from extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
copy to extensions/google-bigquery/runtime/src/main/java/org/apache/camel/quarkus/component/google/bigquery/GoogleBigQueryConnectionFactoryProducer.java
index ecbcd3b..887b9e6 100644
--- a/extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
+++ b/extensions/google-bigquery/runtime/src/main/java/org/apache/camel/quarkus/component/google/bigquery/GoogleBigQueryConnectionFactoryProducer.java
@@ -14,29 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.google.bigquery.it;
+package org.apache.camel.quarkus.component.google.bigquery;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 
-@QuarkusTest
-class GoogleBigqueryTest {
+import com.google.cloud.bigquery.BigQuery;
+import org.apache.camel.component.google.bigquery.GoogleBigQueryConnectionFactory;
 
-    @Test
-    public void loadComponentGoogleBigquery() {
-        /* A simple autogenerated test */
-        RestAssured.get("/google-bigquery/load/component/google-bigquery")
-                .then()
-                .statusCode(200);
-    }
+@ApplicationScoped
+public class GoogleBigQueryConnectionFactoryProducer {
 
-    @Test
-    public void loadComponentGoogleBigquerySql() {
-        /* A simple autogenerated test */
-        RestAssured.get("/google-bigquery/load/component/google-bigquery-sql")
-                .then()
-                .statusCode(200);
-    }
+    @Inject
+    BigQuery bigQuery;
 
+    @Produces
+    @Default
+    @Singleton
+    public GoogleBigQueryConnectionFactory googleBigQueryConnectionFactory() {
+        return new GoogleBigQueryConnectionFactory(bigQuery);
+    }
 }
diff --git a/extensions-jvm/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from extensions-jvm/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 0497407..d8b5e56 100644
--- a/extensions-jvm/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/google-bigquery/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
 name: "Camel Google BigQuery"
 description: "Access Google Cloud BigQuery service using SQL queries or Google Client Services API"
 metadata:
-  unlisted: true
   guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/google-bigquery.html"
   categories:
   - "integration"
   status:
-  - "preview"
+  - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 9beeb7c..d7d5aea 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -109,6 +109,7 @@
         <module>geocoder</module>
         <module>git</module>
         <module>github</module>
+        <module>google-bigquery</module>
         <module>google-calendar</module>
         <module>google-drive</module>
         <module>google-mail</module>
diff --git a/integration-tests/google-bigquery/README.adoc b/integration-tests/google-bigquery/README.adoc
new file mode 100644
index 0000000..d210160
--- /dev/null
+++ b/integration-tests/google-bigquery/README.adoc
@@ -0,0 +1,16 @@
+== Camel Quarkus Google BigQuery Integration Tests
+
+To run Camel Google BigQuery integration tests, you need a valid https://cloud.google.com/[Google Cloud Platform] (GCP) account. Note that the GCP free tier & sandbox
+mode does not provide the required capabilities (streaming inserts & queries) that enable the tests to run successfully.
+
+The simplest means of setting up authentication is via a https://cloud.google.com/docs/authentication/getting-started[service account]. Use the GCP UI to export
+a JSON representation of your credentials.
+
+You should now set the following environment variable:
+
+[source,shell]
+----
+export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
+----
+
+You should also modify `application.properties` so that `quarkus.google.cloud.project-id` is correct for your GCP project.
diff --git a/integration-tests/jsonb/pom.xml b/integration-tests/google-bigquery/pom.xml
similarity index 60%
copy from integration-tests/jsonb/pom.xml
copy to integration-tests/google-bigquery/pom.xml
index 1623b03..6cb792f 100644
--- a/integration-tests/jsonb/pom.xml
+++ b/integration-tests/google-bigquery/pom.xml
@@ -17,49 +17,34 @@
     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">
+<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>1.5.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-integration-test-jsonb</artifactId>
-    <name>Camel Quarkus :: Integration Tests :: JSON JSON-B</name>
-    <description>Integration tests for Camel Quarkus JSON JSON-B extension</description>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.apache.camel.quarkus</groupId>
-                <artifactId>camel-quarkus-bom-test</artifactId>
-                <version>${project.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
+    <artifactId>camel-quarkus-integration-test-google-bigquery</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: Google BigQuery</name>
+    <description>Integration tests for Camel Quarkus Google BigQuery extension</description>
 
     <dependencies>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-jsonb</artifactId>
+            <artifactId>camel-quarkus-google-bigquery</artifactId>
         </dependency>
         <dependency>
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-resteasy</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-direct</artifactId>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jsonb</artifactId>
         </dependency>
         <dependency>
             <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-resteasy-jackson</artifactId>
+            <artifactId>quarkus-resteasy-jsonb</artifactId>
         </dependency>
 
         <!-- test dependencies -->
@@ -77,22 +62,7 @@
         <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-direct-deployment</artifactId>
-            <version>${project.version}</version>
-            <type>pom</type>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>*</groupId>
-                    <artifactId>*</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-jsonb-deployment</artifactId>
+            <artifactId>camel-quarkus-google-bigquery-deployment</artifactId>
             <version>${project.version}</version>
             <type>pom</type>
             <scope>test</scope>
@@ -105,22 +75,6 @@
         </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</id>
diff --git a/integration-tests/google-bigquery/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java b/integration-tests/google-bigquery/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java
new file mode 100644
index 0000000..8bf7af2
--- /dev/null
+++ b/integration-tests/google-bigquery/src/main/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryResource.java
@@ -0,0 +1,105 @@
+/*
+ * 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.quarkus.component.google.bigquery.it;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+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 com.google.cloud.bigquery.BigQuery;
+import org.apache.camel.ProducerTemplate;
+
+@Path("/google-bigquery")
+public class GoogleBigqueryResource {
+
+    public static final String DATASET_ID = "cq_testing";
+    public static final String TABLE_NAME = "camel_quarkus_basic";
+
+    @Inject
+    BigQuery bigQuery;
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    String tableId = DATASET_ID + "." + TABLE_NAME;
+
+    @Path("/table")
+    @POST
+    public Response createTable() {
+        String sql = "CREATE TABLE `" + tableId + "` (id NUMERIC, col1 STRING, col2 STRING)";
+        producerTemplate.requestBody("google-bigquery-sql:" + getProjectId() + ":" + sql, null,
+                Long.class);
+        return Response.created(URI.create("https://camel.apache.org")).build();
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response insertRow(Map<String, String> tableData) {
+        producerTemplate.requestBody("google-bigquery:" + getProjectId() + ":" + DATASET_ID + ":" + TABLE_NAME, tableData);
+        return Response.created(URI.create("https://camel.apache.org")).build();
+    }
+
+    @GET
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getRow() {
+        String sql = "SELECT * FROM `" + tableId + "`";
+        Long rowCount = producerTemplate.requestBody("google-bigquery-sql:" + getProjectId() + ":" + sql, null, Long.class);
+        return Response.ok(rowCount).build();
+    }
+
+    @Path("/file")
+    @GET
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getRowUsingQueryResource() throws IOException {
+        String sql = "SELECT * FROM `" + tableId + "`";
+        java.nio.file.Path path = Files.createTempDirectory("bigquery");
+        java.nio.file.Path sqlFile = Files.createTempFile(path, "bigquery", ".sql");
+        Files.write(sqlFile, sql.getBytes(StandardCharsets.UTF_8));
+
+        Long rowCount = producerTemplate.requestBody(
+                "google-bigquery-sql:" + getProjectId() + ":file:" + sqlFile.toAbsolutePath().toString(),
+                null, Long.class);
+        return Response.ok(rowCount).build();
+    }
+
+    @Path("/table")
+    @DELETE
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response dropTable() {
+        String sql = "DROP TABLE `" + tableId + "`";
+        producerTemplate.requestBody("google-bigquery-sql:" + getProjectId() + ":" + sql, null, Long.class);
+        return Response.ok().build();
+    }
+
+    private String getProjectId() {
+        return bigQuery.getOptions().getProjectId();
+    }
+}
diff --git a/integration-tests/google-bigquery/src/main/resources/application.properties b/integration-tests/google-bigquery/src/main/resources/application.properties
new file mode 100644
index 0000000..dae8729
--- /dev/null
+++ b/integration-tests/google-bigquery/src/main/resources/application.properties
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# Set this to the project id for your GCP BigQuery project
+quarkus.google.cloud.project-id=your-gcp-project-id-here
diff --git a/extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java b/integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryIT.java
similarity index 57%
rename from extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
rename to integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryIT.java
index ecbcd3b..2ebc51b 100644
--- a/extensions-jvm/google-bigquery/integration-test/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
+++ b/integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryIT.java
@@ -16,27 +16,11 @@
  */
 package org.apache.camel.quarkus.component.google.bigquery.it;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import io.quarkus.test.junit.NativeImageTest;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
-@QuarkusTest
-class GoogleBigqueryTest {
-
-    @Test
-    public void loadComponentGoogleBigquery() {
-        /* A simple autogenerated test */
-        RestAssured.get("/google-bigquery/load/component/google-bigquery")
-                .then()
-                .statusCode(200);
-    }
-
-    @Test
-    public void loadComponentGoogleBigquerySql() {
-        /* A simple autogenerated test */
-        RestAssured.get("/google-bigquery/load/component/google-bigquery-sql")
-                .then()
-                .statusCode(200);
-    }
+@NativeImageTest
+@EnabledIfEnvironmentVariable(named = "GOOGLE_APPLICATION_CREDENTIALS", matches = ".+")
+class GoogleBigqueryIT extends GoogleBigqueryTest {
 
 }
diff --git a/integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java b/integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
new file mode 100644
index 0000000..2a71fc5
--- /dev/null
+++ b/integration-tests/google-bigquery/src/test/java/org/apache/camel/quarkus/component/google/bigquery/it/GoogleBigqueryTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.quarkus.component.google.bigquery.it;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import static org.hamcrest.Matchers.is;
+
+@QuarkusTest
+@EnabledIfEnvironmentVariable(named = "GOOGLE_APPLICATION_CREDENTIALS", matches = ".+")
+class GoogleBigqueryTest {
+
+    @Test
+    public void googleBigQueryCrudOperations() {
+        try {
+            // Create table
+            RestAssured.post("/google-bigquery/table")
+                    .then()
+                    .statusCode(201);
+
+            // Insert rows
+            for (int i = 1; i <= 3; i++) {
+                Map<String, String> object = new HashMap<>();
+                object.put("id", String.valueOf(i));
+                object.put("col1", String.valueOf(i + 1));
+                object.put("col2", String.valueOf(i + 2));
+
+                RestAssured.given()
+                        .contentType(ContentType.JSON)
+                        .body(object)
+                        .post("/google-bigquery")
+                        .then()
+                        .statusCode(201);
+            }
+
+            // Verify rows exits
+            RestAssured.get("/google-bigquery")
+                    .then()
+                    .statusCode(200)
+                    .body(is("3"));
+
+            // Verify rows exits using a query resource from the filesystem
+            RestAssured.get("/google-bigquery/file")
+                    .then()
+                    .statusCode(200)
+                    .body(is("3"));
+        } finally {
+            // Delete table
+            RestAssured.delete("/google-bigquery/table")
+                    .then()
+                    .statusCode(200);
+        }
+    }
+}
diff --git a/integration-tests/jsonb/pom.xml b/integration-tests/jsonb/pom.xml
index 1623b03..1ebdb77 100644
--- a/integration-tests/jsonb/pom.xml
+++ b/integration-tests/jsonb/pom.xml
@@ -103,6 +103,19 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsonb-deployment</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index a37f22f..aa71a23 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -99,6 +99,7 @@
         <module>git</module>
         <module>github</module>
         <module>google</module>
+        <module>google-bigquery</module>
         <module>google-pubsub</module>
         <module>graphql</module>
         <module>grok</module>
diff --git a/pom.xml b/pom.xml
index a9209ac..61b3de8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,7 +86,7 @@
         <okio.version>${squareup-okio-version}</okio.version><!-- keep in sync with okhttp -->
         <optaplanner.version>7.46.0.Final</optaplanner.version>
         <quarkus.version>1.10.3.Final</quarkus.version>
-        <quarkus-google-cloud.version>0.2.0</quarkus-google-cloud.version>
+        <quarkus-google-cloud.version>0.3.0</quarkus-google-cloud.version>
         <quarkus-qpid-jms.version>0.21.0</quarkus-qpid-jms.version>
         <protobuf.version>${protobuf-version}</protobuf.version>
         <retrofit.version>2.5.0</retrofit.version>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 3f93063..af065af 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -886,6 +886,16 @@
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-google-bigquery</artifactId>
                 <version>${camel.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>com.google.cloud</groupId>
+                        <artifactId>google-cloud-bigquery</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.google.guava</groupId>
+                        <artifactId>guava</artifactId>
+                    </exclusion>
+                </exclusions>
             </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
@@ -5529,6 +5539,16 @@
             </dependency>
             <dependency>
                 <groupId>io.quarkiverse.googlecloudservices</groupId>
+                <artifactId>quarkus-google-cloud-bigquery</artifactId>
+                <version>${quarkus-google-cloud.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.quarkiverse.googlecloudservices</groupId>
+                <artifactId>quarkus-google-cloud-bigquery-deployment</artifactId>
+                <version>${quarkus-google-cloud.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.quarkiverse.googlecloudservices</groupId>
                 <artifactId>quarkus-google-cloud-pubsub</artifactId>
                 <version>${quarkus-google-cloud.version}</version>
             </dependency>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index c3bcf73..822faa9 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -31,6 +31,7 @@ cloud:
   - azure
   - consul
   - elasticsearch-rest
+  - google-bigquery
   - google-pubsub
   - grpc
   - protobuf