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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0946165  Camel Avro RPC component native support #1941
0946165 is described below

commit 0946165ba3b644f568043420dfaf6b60e1e25cfc
Author: JiriOndrusek <ondrusek.j...@gmail.com>
AuthorDate: Tue Nov 24 11:14:08 2020 +0100

    Camel Avro RPC component native support #1941
---
 .../ROOT/pages/reference/extensions/avro-rpc.adoc  |  13 +-
 .../ROOT/partials/reference/components/avro.adoc   |   6 +-
 .../component/avro/deployment/AvroProcessor.java   |  58 ----
 extensions-jvm/avro-rpc/integration-test/pom.xml   |  66 ----
 .../quarkus/component/avro/it/AvroResource.java    |  51 ----
 extensions-jvm/pom.xml                             |   1 -
 .../avro-rpc/deployment/pom.xml                    |   8 +-
 .../avro/rpc/deployment/AvroRpcProcessor.java      |  54 ++++
 {extensions-jvm => extensions}/avro-rpc/pom.xml    |   5 +-
 .../avro-rpc/runtime/pom.xml                       |  31 +-
 .../avro-rpc/runtime/src/main/doc/usage.adoc       |   1 +
 .../avro/rpc/GenericDatumReaderSubstitute.java     |  56 ++++
 .../main/resources/META-INF/quarkus-extension.yaml |   3 +-
 extensions/pom.xml                                 |   1 +
 integration-tests/avro-rpc/pom.xml                 | 150 +++++++++
 integration-tests/avro-rpc/src/main/avro/test.avpr |  27 ++
 .../component/avro/rpc/it/AvroRpcResource.java     | 152 ++++++++++
 .../component/avro/rpc/it/AvroRpcRouteBuilder.java |  69 +++++
 .../component/avro/rpc/it/ProtocolType.java        |  15 +-
 .../rpc/it/reflection/ReflectionProcessor.java     |  23 +-
 .../component/avro/rpc/it/reflection/TestPojo.java |  19 +-
 .../avro/rpc/it/reflection/TestReflection.java     |  20 +-
 .../rpc/it/reflection/impl/TestReflectionImpl.java |  34 ++-
 .../avro/rpc/it/specific/PutProcessor.java         |  43 +++
 .../avro/rpc/it/specific/generated/Key.java        | 336 +++++++++++++++++++++
 .../it/specific/generated/KeyValueProtocol.java    |  41 +++
 .../avro/rpc/it/specific/generated/Value.java      | 336 +++++++++++++++++++++
 .../rpc/it/specific/impl/KeyValueProtocolImpl.java |  30 +-
 .../component/avro/rpc/it/AvroRpcHttpIT.java       |  14 +-
 .../component/avro/rpc/it/AvroRpcHttpTest.java     |  14 +-
 .../component/avro/rpc/it/AvroRpcNettyIT.java      |  14 +-
 .../component/avro/rpc/it/AvroRpcNettyTest.java    |  15 +-
 .../component/avro/rpc/it/AvroRpcTestResource.java | 122 ++++++++
 .../component/avro/rpc/it/AvroRpcTestSupport.java  | 204 +++++++++++++
 integration-tests/pom.xml                          |   1 +
 pom.xml                                            |   2 +
 poms/bom/pom.xml                                   |  15 +
 tooling/scripts/test-categories.yaml               |   1 +
 38 files changed, 1769 insertions(+), 282 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/avro-rpc.adoc 
b/docs/modules/ROOT/pages/reference/extensions/avro-rpc.adoc
index 38c7c2a..b587ba4 100644
--- a/docs/modules/ROOT/pages/reference/extensions/avro-rpc.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/avro-rpc.adoc
@@ -3,15 +3,15 @@
 = Avro RPC
 :page-aliases: extensions/avro-rpc.adoc
 :cq-artifact-id: camel-quarkus-avro-rpc
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-description: Produce or consume Apache Avro RPC services.
 :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##
 
 Produce or consume Apache Avro RPC services.
 
@@ -32,3 +32,8 @@ 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.
+
+== Usage
+
+Classes used as the protocol (either specific or reflective) in native mode, 
have to be registered for reflection (see 
https://quarkus.io/guides/writing-native-applications-tips#register-reflection[documentation]).
+
diff --git a/docs/modules/ROOT/partials/reference/components/avro.adoc 
b/docs/modules/ROOT/partials/reference/components/avro.adoc
index c65eded..401e1ce 100644
--- a/docs/modules/ROOT/partials/reference/components/avro.adoc
+++ b/docs/modules/ROOT/partials/reference/components/avro.adoc
@@ -2,11 +2,11 @@
 // This file was generated by 
camel-quarkus-maven-plugin:update-extension-doc-page
 :cq-artifact-id: camel-quarkus-avro-rpc
 :cq-artifact-id-base: avro-rpc
-: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: avro
 :cq-camel-part-title: Avro RPC
 :cq-camel-part-description: Produce or consume Apache Avro RPC services.
diff --git 
a/extensions-jvm/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java
 
b/extensions-jvm/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java
deleted file mode 100644
index ecd525b..0000000
--- 
a/extensions-jvm/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java
+++ /dev/null
@@ -1,58 +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.avro.deployment;
-
-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.component.avro.AvroComponent;
-import org.apache.camel.quarkus.component.avro.AvroRecorder;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
-import org.jboss.logging.Logger;
-
-class AvroProcessor {
-
-    private static final Logger LOG = Logger.getLogger(AvroProcessor.class);
-    private static final String FEATURE = "camel-avro-rpc";
-
-    @BuildStep
-    FeatureBuildItem feature() {
-        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
-    }
-
-    @Record(ExecutionTime.STATIC_INIT)
-    @BuildStep
-    CamelBeanBuildItem avroComponent(AvroRecorder recorder) {
-        return new CamelBeanBuildItem(
-                "avro-rpc",
-                AvroComponent.class.getName(),
-                recorder.createAvroComponent());
-    }
-}
diff --git a/extensions-jvm/avro-rpc/integration-test/pom.xml 
b/extensions-jvm/avro-rpc/integration-test/pom.xml
deleted file mode 100644
index 6358565..0000000
--- a/extensions-jvm/avro-rpc/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-avro-rpc-integration-test</artifactId>
-    <name>Camel Quarkus :: Avro RPC :: Integration Test</name>
-    <description>Integration tests for Camel Quarkus Avro 
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-avro-rpc-deployment</mvnd.builder.rule>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-avro-rpc</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/avro-rpc/integration-test/src/main/java/org/apache/camel/quarkus/component/avro/it/AvroResource.java
 
b/extensions-jvm/avro-rpc/integration-test/src/main/java/org/apache/camel/quarkus/component/avro/it/AvroResource.java
deleted file mode 100644
index 99f5473..0000000
--- 
a/extensions-jvm/avro-rpc/integration-test/src/main/java/org/apache/camel/quarkus/component/avro/it/AvroResource.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.avro.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("/avro")
-@ApplicationScoped
-public class AvroResource {
-
-    private static final Logger LOG = Logger.getLogger(AvroResource.class);
-
-    private static final String COMPONENT_AVRO = "avro-rpc";
-    @Inject
-    CamelContext context;
-
-    @Path("/load/component/avro")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentAvro() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_AVRO) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", 
COMPONENT_AVRO);
-        return Response.status(500, COMPONENT_AVRO + " could not be loaded 
from the Camel context").build();
-    }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 7c524d1..bdedb7f 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -39,7 +39,6 @@
         <module>asterisk</module>
         <module>atmos</module>
         <module>atomix</module>
-        <module>avro-rpc</module>
         <module>aws-xray</module>
         <module>aws2-eventbridge</module>
         <module>aws2-kinesis</module>
diff --git a/extensions-jvm/avro-rpc/deployment/pom.xml 
b/extensions/avro-rpc/deployment/pom.xml
similarity index 86%
rename from extensions-jvm/avro-rpc/deployment/pom.xml
rename to extensions/avro-rpc/deployment/pom.xml
index 5c42138..c6833f1 100644
--- a/extensions-jvm/avro-rpc/deployment/pom.xml
+++ b/extensions/avro-rpc/deployment/pom.xml
@@ -17,7 +17,9 @@
     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>
@@ -38,6 +40,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-avro-rpc</artifactId>
         </dependency>
+        <dependency>
+            <artifactId>quarkus-avro-deployment</artifactId>
+            <groupId>io.quarkus</groupId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/extensions/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/rpc/deployment/AvroRpcProcessor.java
 
b/extensions/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/rpc/deployment/AvroRpcProcessor.java
new file mode 100644
index 0000000..ced61ba
--- /dev/null
+++ 
b/extensions/avro-rpc/deployment/src/main/java/org/apache/camel/quarkus/component/avro/rpc/deployment/AvroRpcProcessor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.avro.rpc.deployment;
+
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import org.apache.avro.specific.AvroGenerated;
+import org.jboss.jandex.AnnotationTarget;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.IndexView;
+
+class AvroRpcProcessor {
+
+    private static final String FEATURE = "camel-avro-rpc";
+
+    @BuildStep
+    FeatureBuildItem feature() {
+        return new FeatureBuildItem(FEATURE);
+    }
+
+    @BuildStep
+    ReflectiveClassBuildItem registerForReflection(CombinedIndexBuildItem 
combinedIndex) {
+        IndexView index = combinedIndex.getIndex();
+        String[] dtos = 
index.getAnnotations(DotName.createSimple(AvroGenerated.class.getName())).stream()
+                .filter(a -> a.target().kind() == AnnotationTarget.Kind.CLASS)
+                .map(a -> a.target().asClass().name().toString())
+                .toArray(String[]::new);
+
+        return new ReflectiveClassBuildItem(false, false, dtos);
+    }
+
+    @BuildStep
+    void registerDependencyForIndex(BuildProducer<IndexDependencyBuildItem> 
indexDependency) {
+        indexDependency.produce(new 
IndexDependencyBuildItem("org.apache.avro", "avro-ipc"));
+    }
+}
diff --git a/extensions-jvm/avro-rpc/pom.xml b/extensions/avro-rpc/pom.xml
similarity index 84%
rename from extensions-jvm/avro-rpc/pom.xml
rename to extensions/avro-rpc/pom.xml
index 33d9505..d46bb05 100644
--- a/extensions-jvm/avro-rpc/pom.xml
+++ b/extensions/avro-rpc/pom.xml
@@ -17,7 +17,9 @@
     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>
@@ -33,6 +35,5 @@
     <modules>
         <module>deployment</module>
         <module>runtime</module>
-        <module>integration-test</module>
     </modules>
 </project>
diff --git a/extensions-jvm/avro-rpc/runtime/pom.xml 
b/extensions/avro-rpc/runtime/pom.xml
similarity index 76%
rename from extensions-jvm/avro-rpc/runtime/pom.xml
rename to extensions/avro-rpc/runtime/pom.xml
index 8448302..ffbe080 100644
--- a/extensions-jvm/avro-rpc/runtime/pom.xml
+++ b/extensions/avro-rpc/runtime/pom.xml
@@ -17,7 +17,9 @@
     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>
@@ -28,10 +30,11 @@
 
     <artifactId>camel-quarkus-avro-rpc</artifactId>
     <name>Camel Quarkus :: Avro RPC :: Runtime</name>
+    <description>Produce or consume Apache Avro RPC services.</description>
 
     <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>
@@ -54,6 +57,29 @@
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-avro-rpc</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>*</artifactId>
+                    <groupId>org.apache.avro</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <artifactId>quarkus-avro</artifactId>
+            <groupId>io.quarkus</groupId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.avro</groupId>
+            <artifactId>avro-ipc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.avro</groupId>
+            <artifactId>avro-ipc-jetty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.graalvm.nativeimage</groupId>
+            <artifactId>svm</artifactId>
+            <scope>provided</scope>
         </dependency>
     </dependencies>
 
@@ -79,6 +105,7 @@
         </plugins>
     </build>
 
+
     <profiles>
         <profile>
             <id>full</id>
diff --git a/extensions/avro-rpc/runtime/src/main/doc/usage.adoc 
b/extensions/avro-rpc/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000..4a27875
--- /dev/null
+++ b/extensions/avro-rpc/runtime/src/main/doc/usage.adoc
@@ -0,0 +1 @@
+Classes used as the protocol (either specific or reflective) in native mode, 
have to be registered for reflection (see 
https://quarkus.io/guides/writing-native-applications-tips#register-reflection[documentation]).
\ No newline at end of file
diff --git 
a/extensions/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/rpc/GenericDatumReaderSubstitute.java
 
b/extensions/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/rpc/GenericDatumReaderSubstitute.java
new file mode 100644
index 0000000..5ecb7c5
--- /dev/null
+++ 
b/extensions/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/rpc/GenericDatumReaderSubstitute.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.avro.rpc;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.Inject;
+import com.oracle.svm.core.annotate.RecomputeFieldValue;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericDatumReader;
+
+@TargetClass(value = GenericDatumReader.class)
+public final class GenericDatumReaderSubstitute {
+
+    @Inject
+    @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset)
+    private Map<Schema, Class> stringClassCache;
+
+    @Alias
+    protected Class findStringClass(Schema schema) {
+        return null;
+    }
+
+    @Substitute
+    private Class getStringClass(Schema s) {
+        if (stringClassCache == null) {
+            stringClassCache = new IdentityHashMap<>();
+        }
+
+        Class c = stringClassCache.get(s);
+
+        if (c == null) {
+            c = findStringClass(s);
+            stringClassCache.put(s, c);
+        }
+        return c;
+    }
+}
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
 
b/extensions/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from 
extensions-jvm/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to 
extensions/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 4793113..ffd4ddd 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ 
b/extensions/avro-rpc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
 name: "Camel Avro RPC"
 description: "Produce or consume Apache Avro RPC services"
 metadata:
-  unlisted: true
   guide: 
"https://camel.apache.org/camel-quarkus/latest/reference/extensions/avro-rpc.html";
   categories:
   - "integration"
   status:
-  - "preview"
+  - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 4a4e92e..db898d1 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -42,6 +42,7 @@
         <module>atom</module>
         <module>attachments</module>
         <module>avro</module>
+        <module>avro-rpc</module>
         <module>aws-ec2</module>
         <module>aws-ecs</module>
         <module>aws-eks</module>
diff --git a/integration-tests/avro-rpc/pom.xml 
b/integration-tests/avro-rpc/pom.xml
new file mode 100644
index 0000000..1fdfd2a
--- /dev/null
+++ b/integration-tests/avro-rpc/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/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-avro-rpc</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: Avro RPC</name>
+    <description>Integration tests for Camel Quarkus Avro RPC 
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-avro-rpc</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-test-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-avro-rpc-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>
+
+        <!-- Profile for generation of protocol files into package 
`org.apache.camel.quarkus.component.avro.rpc.it.specific.generated` -->
+        <profile>
+            <id>avro</id>
+            <activation>
+                <property>
+                    <name>!quickly</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.avro</groupId>
+                        <artifactId>avro-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>schema</goal>
+                                    <goal>protocol</goal>
+                                    <goal>idl-protocol</goal>
+                                </goals>
+                                <configuration>
+                                    
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
+                                    
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/integration-tests/avro-rpc/src/main/avro/test.avpr 
b/integration-tests/avro-rpc/src/main/avro/test.avpr
new file mode 100644
index 0000000..96eea98
--- /dev/null
+++ b/integration-tests/avro-rpc/src/main/avro/test.avpr
@@ -0,0 +1,27 @@
+{"namespace": 
"org.apache.camel.quarkus.component.avro.rpc.it.specific.generated",
+ "protocol": "KeyValueProtocol",
+
+ "types": [
+     {"name": "Key", "type": "record",
+      "fields": [
+          {"name": "key",   "type": "string"}
+      ]
+     },
+     {"name": "Value", "type": "record",
+      "fields": [
+          {"name": "value",   "type": "string"}
+      ]
+     }
+ ],
+
+ "messages": {
+     "put": {
+         "request": [{"name": "key", "type": "Key"}, {"name": "value", "type": 
"Value"} ],
+         "response": "null"
+     },
+     "get": {
+         "request": [{"name": "key", "type": "Key"}],
+         "response": "Value"
+     }
+ }
+}
\ No newline at end of file
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcResource.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcResource.java
new file mode 100644
index 0000000..63d0c96
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcResource.java
@@ -0,0 +1,152 @@
+/*
+ * 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.avro.rpc.it;
+
+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.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestPojo;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestReflection;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.impl.TestReflectionImpl;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.impl.KeyValueProtocolImpl;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@Path("/avro-rpc")
+@ApplicationScoped
+public class AvroRpcResource {
+
+    public static final String REFLECTIVE_HTTP_SERVER_PORT_PARAM = 
"camel.avro-rpc.test.reflective.httpServerReflection.port";
+    public static final String REFLECTIVE_NETTY_SERVER_PORT_PARAM = 
"camel.avro-rpc.test.reflective.nettyServerReflection.port";
+    public static final String SPECIFIC_HTTP_SERVER_PORT_PARAM = 
"camel.avro-rpc.test.generated.httpServerReflection.port";
+    public static final String SPECIFIC_NETTY_SERVER_PORT_PARAM = 
"camel.avro-rpc.test.generated.nettyServerReflection.port";
+    public static final String REFLECTIVE_HTTP_TRANSCEIVER_PORT_PARAM = 
"camel.avro-rpc.test.httpTransceiverReflection.port";
+    public static final String REFLECTIVE_NETTY_TRANSCEIVER_PORT_PARAM = 
"camel.avro-rpc.test.nettyTransceiverReflection.port";
+    public static final String SPECIFIC_HTTP_TRANSCEIVER_PORT_PARAM = 
"camel.avro-rpc.test.specific.httpTransceiverReflection.port";
+    public static final String SPECIFIC_NETTY_TRANSCEIVER_PORT_PARAM = 
"camel.avro-rpc.test.specific.nettyTransceiverReflection.port";
+
+    private TestReflection httpTestReflection = new TestReflectionImpl(),
+            nettyTestReflection = new TestReflectionImpl();
+    private KeyValueProtocol httpKeyValue = new KeyValueProtocolImpl(),
+            nettyKeyValue = new KeyValueProtocolImpl();
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @ConfigProperty(name = REFLECTIVE_HTTP_SERVER_PORT_PARAM)
+    Integer reflectiveHttpPort;
+
+    @ConfigProperty(name = REFLECTIVE_NETTY_SERVER_PORT_PARAM)
+    Integer reflectiveNettyPort;
+
+    @ConfigProperty(name = SPECIFIC_HTTP_SERVER_PORT_PARAM)
+    Integer specificHttpPort;
+
+    @ConfigProperty(name = SPECIFIC_NETTY_SERVER_PORT_PARAM)
+    Integer specificNettyPort;
+
+    @Path("/reflectionProducerSet")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    public void reflectionProducerSet(@QueryParam("protocol") ProtocolType 
protocol, String name) throws Exception {
+        Object[] request = { name };
+        producerTemplate.requestBody(String.format(
+                
"avro:%s:localhost:%d/setName?protocolClassName=%s&singleParameter=true",
+                protocol,
+                protocol == ProtocolType.http ? reflectiveHttpPort : 
reflectiveNettyPort,
+                TestReflection.class.getCanonicalName()), request);
+    }
+
+    @Path("/reflectionProducerGet")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String reflectionProducerGet(ProtocolType protocol) throws 
Exception {
+        return producerTemplate.requestBody(String.format(
+                "avro:%s:localhost:%d/getName?protocolClassName=%s",
+                protocol,
+                protocol == ProtocolType.http ? reflectiveHttpPort : 
reflectiveNettyPort,
+                TestReflection.class.getCanonicalName()), null, String.class);
+    }
+
+    @Path("/specificProducerPut")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    public void specificProducerPut(@QueryParam("protocol") ProtocolType 
protocol, @QueryParam("key") String key, String value)
+            throws Exception {
+        Key k = Key.newBuilder().setKey(key).build();
+        Value v = Value.newBuilder().setValue(value).build();
+
+        Object[] request = { k, v };
+        producerTemplate.requestBody(String.format(
+                "avro:%s:localhost:%d/put?protocolClassName=%s",
+                protocol,
+                protocol == ProtocolType.http ? specificHttpPort : 
specificNettyPort,
+                KeyValueProtocol.class.getCanonicalName()), request);
+    }
+
+    @Path("/specificProducerGet")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String specificProducerGet(@QueryParam("protocol") ProtocolType 
protocol, String key) throws Exception {
+        Key k = Key.newBuilder().setKey(key).build();
+
+        Object[] request = { k };
+        return producerTemplate.requestBody(String.format(
+                
"avro:%s:localhost:%d/get?protocolClassName=%s&singleParameter=true",
+                protocol,
+                protocol == ProtocolType.http ? specificHttpPort : 
specificNettyPort,
+                KeyValueProtocol.class.getCanonicalName()), request, 
String.class);
+    }
+
+    @Path("/reflectionConsumerGet")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String reflectionConsumerGet(ProtocolType protocol) throws 
Exception {
+        TestPojo testPojo = getTestReflection(protocol).getTestPojo();
+        return testPojo != null ? testPojo.getPojoName() : null;
+    }
+
+    @Path("/specificConsumerGet")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String specificConsumerGet(@QueryParam("protocol") ProtocolType 
protocol, String key) throws Exception {
+        Key k = Key.newBuilder().setKey(key).build();
+
+        return getKeyValue(protocol).get(k).toString();
+    }
+
+    public TestReflection getTestReflection(ProtocolType protocol) {
+        return protocol == ProtocolType.http ? httpTestReflection : 
nettyTestReflection;
+    }
+
+    public KeyValueProtocol getKeyValue(ProtocolType protocol) {
+        return protocol == ProtocolType.http ? httpKeyValue : nettyKeyValue;
+    }
+}
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcRouteBuilder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcRouteBuilder.java
new file mode 100644
index 0000000..59e2b77
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcRouteBuilder.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.quarkus.component.avro.rpc.it;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.apache.camel.builder.RouteBuilder;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.ReflectionProcessor;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestReflection;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.PutProcessor;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@ApplicationScoped
+public class AvroRpcRouteBuilder extends RouteBuilder {
+    public static final String DIRECT_START = "direct:start";
+
+    @ConfigProperty(name = 
AvroRpcResource.REFLECTIVE_HTTP_TRANSCEIVER_PORT_PARAM)
+    Integer httpPort;
+
+    @ConfigProperty(name = 
AvroRpcResource.REFLECTIVE_NETTY_TRANSCEIVER_PORT_PARAM)
+    Integer nettyPort;
+
+    @ConfigProperty(name = 
AvroRpcResource.SPECIFIC_HTTP_TRANSCEIVER_PORT_PARAM)
+    Integer specificHttpPort;
+
+    @ConfigProperty(name = 
AvroRpcResource.SPECIFIC_NETTY_TRANSCEIVER_PORT_PARAM)
+    Integer specificNettyPort;
+
+    @Inject
+    AvroRpcResource avroRpcResource;
+
+    @Override
+    public void configure() throws Exception {
+
+        
from(String.format("avro:http:localhost:%d/setTestPojo?protocolClassName=%s&singleParameter=true",
 httpPort,
+                TestReflection.class.getCanonicalName()))
+                        .process(new 
ReflectionProcessor(avroRpcResource.getTestReflection(ProtocolType.http)));
+
+        
from(String.format("avro:netty:localhost:%d/setTestPojo?protocolClassName=%s&singleParameter=true",
 nettyPort,
+                TestReflection.class.getCanonicalName()))
+                        .process(new 
ReflectionProcessor(avroRpcResource.getTestReflection(ProtocolType.netty)));
+
+        from(String.format("avro:http:localhost:%d/put?protocolClassName=%s", 
specificHttpPort,
+                KeyValueProtocol.class.getCanonicalName()))
+                        .process(new 
PutProcessor(avroRpcResource.getKeyValue(ProtocolType.http)));
+
+        from(String.format("avro:netty:localhost:%d/put?protocolClassName=%s", 
specificNettyPort,
+                KeyValueProtocol.class.getCanonicalName()))
+                        .process(new 
PutProcessor(avroRpcResource.getKeyValue(ProtocolType.netty)));
+
+    }
+}
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/ProtocolType.java
similarity index 70%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/ProtocolType.java
index 52fe2b8..3facbc7 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/ProtocolType.java
@@ -14,17 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
-
-@Recorder
-public class AvroRecorder {
-
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
-    }
+package org.apache.camel.quarkus.component.avro.rpc.it;
 
+public enum ProtocolType {
+    http, netty
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/ReflectionProcessor.java
similarity index 58%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/ReflectionProcessor.java
index 52fe2b8..0dd89e8 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/ReflectionProcessor.java
@@ -14,17 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it.reflection;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 
-@Recorder
-public class AvroRecorder {
+public class ReflectionProcessor implements Processor {
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
+    private final TestReflection testReflection;
+
+    public ReflectionProcessor(TestReflection testReflection) {
+        this.testReflection = testReflection;
     }
 
+    @Override
+    public void process(Exchange exchange) {
+        Object body = exchange.getIn().getBody();
+        if (body instanceof TestPojo) {
+            testReflection.setTestPojo((TestPojo) body);
+        }
+    }
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestPojo.java
similarity index 69%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestPojo.java
index 52fe2b8..7751eb5 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestPojo.java
@@ -14,17 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it.reflection;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import io.quarkus.runtime.annotations.RegisterForReflection;
 
-@Recorder
-public class AvroRecorder {
+@RegisterForReflection
+public class TestPojo {
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
+    private String pojoName;
+
+    public String getPojoName() {
+        return pojoName;
     }
 
+    public void setPojoName(String pojoName) {
+        this.pojoName = pojoName;
+    }
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestReflection.java
similarity index 70%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestReflection.java
index 52fe2b8..9fb3fac 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/TestReflection.java
@@ -14,17 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it.reflection;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import io.quarkus.runtime.annotations.RegisterForReflection;
 
-@Recorder
-public class AvroRecorder {
+@RegisterForReflection
+public interface TestReflection {
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
-    }
+    String getName();
+
+    void setName(String name);
+
+    void setTestPojo(TestPojo testPojo);
+
+    TestPojo getTestPojo();
 
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/impl/TestReflectionImpl.java
similarity index 54%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/impl/TestReflectionImpl.java
index 52fe2b8..b9d4aa3 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/reflection/impl/TestReflectionImpl.java
@@ -14,17 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it.reflection.impl;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestPojo;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestReflection;
 
-@Recorder
-public class AvroRecorder {
+public class TestReflectionImpl implements TestReflection {
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
+    String name = "";
+    int age;
+    TestPojo testPojo;
+
+    @Override
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void setTestPojo(TestPojo testPojo) {
+        this.testPojo = testPojo;
+    }
+
+    @Override
+    public TestPojo getTestPojo() {
+        return testPojo;
     }
 
 }
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/PutProcessor.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/PutProcessor.java
new file mode 100644
index 0000000..38b4393
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/PutProcessor.java
@@ -0,0 +1,43 @@
+/*
+ * 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.avro.rpc.it.specific;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value;
+
+public class PutProcessor implements Processor {
+
+    private KeyValueProtocol keyValue;
+
+    public PutProcessor(KeyValueProtocol keyValue) {
+        this.keyValue = keyValue;
+    }
+
+    @Override
+    public void process(Exchange exchange) {
+        Object body = exchange.getIn().getBody();
+        if (body instanceof Object[]) {
+            Object[] args = (Object[]) body;
+            if (args.length == 2 && args[0] instanceof Key && args[1] 
instanceof Value) {
+                keyValue.put((Key) args[0], (Value) args[1]);
+            }
+        }
+    }
+}
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Key.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Key.java
new file mode 100644
index 0000000..508e3a6
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Key.java
@@ -0,0 +1,336 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.camel.quarkus.component.avro.rpc.it.specific.generated;
+
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.SchemaStore;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+
+@org.apache.avro.specific.AvroGenerated
+public class Key extends org.apache.avro.specific.SpecificRecordBase 
implements org.apache.avro.specific.SpecificRecord {
+    private static final long serialVersionUID = -1622555054919462235L;
+    public static final org.apache.avro.Schema SCHEMA$ = new 
org.apache.avro.Schema.Parser().parse(
+            
"{\"type\":\"record\",\"name\":\"Key\",\"namespace\":\"org.apache.camel.quarkus.component.avro.rpc.it.specific.generated\",\"fields\":[{\"name\":\"key\",\"type\":\"string\"}]}");
+
+    public static org.apache.avro.Schema getClassSchema() {
+        return SCHEMA$;
+    }
+
+    private static SpecificData MODEL$ = new SpecificData();
+
+    private static final BinaryMessageEncoder<Key> ENCODER = new 
BinaryMessageEncoder<Key>(MODEL$, SCHEMA$);
+
+    private static final BinaryMessageDecoder<Key> DECODER = new 
BinaryMessageDecoder<Key>(MODEL$, SCHEMA$);
+
+    /**
+     * Return the BinaryMessageEncoder instance used by this class.
+     * 
+     * @return the message encoder used by this class
+     */
+    public static BinaryMessageEncoder<Key> getEncoder() {
+        return ENCODER;
+    }
+
+    /**
+     * Return the BinaryMessageDecoder instance used by this class.
+     * 
+     * @return the message decoder used by this class
+     */
+    public static BinaryMessageDecoder<Key> getDecoder() {
+        return DECODER;
+    }
+
+    /**
+     * Create a new BinaryMessageDecoder instance for this class that uses the 
specified {@link SchemaStore}.
+     * 
+     * @param  resolver a {@link SchemaStore} used to find schemas by 
fingerprint
+     * @return          a BinaryMessageDecoder instance for this class backed 
by the given SchemaStore
+     */
+    public static BinaryMessageDecoder<Key> createDecoder(SchemaStore 
resolver) {
+        return new BinaryMessageDecoder<Key>(MODEL$, SCHEMA$, resolver);
+    }
+
+    /**
+     * Serializes this Key to a ByteBuffer.
+     * 
+     * @return                     a buffer holding the serialized data for 
this instance
+     * @throws java.io.IOException if this instance could not be serialized
+     */
+    public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+        return ENCODER.encode(this);
+    }
+
+    /**
+     * Deserializes a Key from a ByteBuffer.
+     * 
+     * @param  b                   a byte buffer holding serialized data for 
an instance of this class
+     * @return                     a Key instance decoded from the given buffer
+     * @throws java.io.IOException if the given bytes could not be 
deserialized into an instance of this class
+     */
+    public static Key fromByteBuffer(
+            java.nio.ByteBuffer b) throws java.io.IOException {
+        return DECODER.decode(b);
+    }
+
+    private java.lang.CharSequence key;
+
+    /**
+     * Default constructor. Note that this does not initialize fields
+     * to their default values from the schema. If that is desired then
+     * one should use <code>newBuilder()</code>.
+     */
+    public Key() {
+    }
+
+    /**
+     * All-args constructor.
+     * 
+     * @param key The new value for key
+     */
+    public Key(java.lang.CharSequence key) {
+        this.key = key;
+    }
+
+    public org.apache.avro.specific.SpecificData getSpecificData() {
+        return MODEL$;
+    }
+
+    public org.apache.avro.Schema getSchema() {
+        return SCHEMA$;
+    }
+
+    // Used by DatumWriter.  Applications should not call.
+    public java.lang.Object get(int field$) {
+        switch (field$) {
+        case 0:
+            return key;
+        default:
+            throw new IndexOutOfBoundsException("Invalid index: " + field$);
+        }
+    }
+
+    // Used by DatumReader.  Applications should not call.
+    @SuppressWarnings(value = "unchecked")
+    public void put(int field$, java.lang.Object value$) {
+        switch (field$) {
+        case 0:
+            key = (java.lang.CharSequence) value$;
+            break;
+        default:
+            throw new IndexOutOfBoundsException("Invalid index: " + field$);
+        }
+    }
+
+    /**
+     * Gets the value of the 'key' field.
+     * 
+     * @return The value of the 'key' field.
+     */
+    public java.lang.CharSequence getKey() {
+        return key;
+    }
+
+    /**
+     * Sets the value of the 'key' field.
+     * 
+     * @param value the value to set.
+     */
+    public void setKey(java.lang.CharSequence value) {
+        this.key = value;
+    }
+
+    /**
+     * Creates a new Key RecordBuilder.
+     * 
+     * @return A new Key RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
newBuilder() {
+        return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder();
+    }
+
+    /**
+     * Creates a new Key RecordBuilder by copying an existing Builder.
+     * 
+     * @param  other The existing builder to copy.
+     * @return       A new Key RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
newBuilder(
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
other) {
+        if (other == null) {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder();
+        } else {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder(other);
+        }
+    }
+
+    /**
+     * Creates a new Key RecordBuilder by copying an existing Key instance.
+     * 
+     * @param  other The existing instance to copy.
+     * @return       A new Key RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
newBuilder(
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key other) {
+        if (other == null) {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder();
+        } else {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder(other);
+        }
+    }
+
+    /**
+     * RecordBuilder for Key instances.
+     */
+    @org.apache.avro.specific.AvroGenerated
+    public static class Builder extends 
org.apache.avro.specific.SpecificRecordBuilderBase<Key>
+            implements org.apache.avro.data.RecordBuilder<Key> {
+
+        private java.lang.CharSequence key;
+
+        /** Creates a new Builder */
+        private Builder() {
+            super(SCHEMA$);
+        }
+
+        /**
+         * Creates a Builder by copying an existing Builder.
+         * 
+         * @param other The existing Builder to copy.
+         */
+        private 
Builder(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder
 other) {
+            super(other);
+            if (isValidValue(fields()[0], other.key)) {
+                this.key = data().deepCopy(fields()[0].schema(), other.key);
+                fieldSetFlags()[0] = other.fieldSetFlags()[0];
+            }
+        }
+
+        /**
+         * Creates a Builder by copying an existing Key instance
+         * 
+         * @param other The existing instance to copy.
+         */
+        private 
Builder(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key 
other) {
+            super(SCHEMA$);
+            if (isValidValue(fields()[0], other.key)) {
+                this.key = data().deepCopy(fields()[0].schema(), other.key);
+                fieldSetFlags()[0] = true;
+            }
+        }
+
+        /**
+         * Gets the value of the 'key' field.
+         * 
+         * @return The value.
+         */
+        public java.lang.CharSequence getKey() {
+            return key;
+        }
+
+        /**
+         * Sets the value of the 'key' field.
+         * 
+         * @param  value The value of 'key'.
+         * @return       This builder.
+         */
+        public 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
setKey(
+                java.lang.CharSequence value) {
+            validate(fields()[0], value);
+            this.key = value;
+            fieldSetFlags()[0] = true;
+            return this;
+        }
+
+        /**
+         * Checks whether the 'key' field has been set.
+         * 
+         * @return True if the 'key' field has been set, false otherwise.
+         */
+        public boolean hasKey() {
+            return fieldSetFlags()[0];
+        }
+
+        /**
+         * Clears the value of the 'key' field.
+         * 
+         * @return This builder.
+         */
+        public 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key.Builder 
clearKey() {
+            key = null;
+            fieldSetFlags()[0] = false;
+            return this;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Key build() {
+            try {
+                Key record = new Key();
+                record.key = fieldSetFlags()[0] ? this.key : 
(java.lang.CharSequence) defaultValue(fields()[0]);
+                return record;
+            } catch (org.apache.avro.AvroMissingFieldException e) {
+                throw e;
+            } catch (java.lang.Exception e) {
+                throw new org.apache.avro.AvroRuntimeException(e);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static final org.apache.avro.io.DatumWriter<Key> WRITER$ = 
(org.apache.avro.io.DatumWriter<Key>) MODEL$
+            .createDatumWriter(SCHEMA$);
+
+    @Override
+    public void writeExternal(java.io.ObjectOutput out)
+            throws java.io.IOException {
+        WRITER$.write(this, SpecificData.getEncoder(out));
+    }
+
+    @SuppressWarnings("unchecked")
+    private static final org.apache.avro.io.DatumReader<Key> READER$ = 
(org.apache.avro.io.DatumReader<Key>) MODEL$
+            .createDatumReader(SCHEMA$);
+
+    @Override
+    public void readExternal(java.io.ObjectInput in)
+            throws java.io.IOException {
+        READER$.read(this, SpecificData.getDecoder(in));
+    }
+
+    @Override
+    protected boolean hasCustomCoders() {
+        return true;
+    }
+
+    @Override
+    public void customEncode(org.apache.avro.io.Encoder out)
+            throws java.io.IOException {
+        out.writeString(this.key);
+
+    }
+
+    @Override
+    public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+            throws java.io.IOException {
+        org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+        if (fieldOrder == null) {
+            this.key = in.readString(this.key instanceof Utf8 ? (Utf8) 
this.key : null);
+
+        } else {
+            for (int i = 0; i < 1; i++) {
+                switch (fieldOrder[i].pos()) {
+                case 0:
+                    this.key = in.readString(this.key instanceof Utf8 ? (Utf8) 
this.key : null);
+                    break;
+
+                default:
+                    throw new java.io.IOException("Corrupt ResolvingDecoder.");
+                }
+            }
+        }
+    }
+}
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/KeyValueProtocol.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/KeyValueProtocol.java
new file mode 100644
index 0000000..1c62544
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/KeyValueProtocol.java
@@ -0,0 +1,41 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.camel.quarkus.component.avro.rpc.it.specific.generated;
+
+@org.apache.avro.specific.AvroGenerated
+public interface KeyValueProtocol {
+    public static final org.apache.avro.Protocol PROTOCOL = 
org.apache.avro.Protocol.parse(
+            
"{\"protocol\":\"KeyValueProtocol\",\"namespace\":\"org.apache.camel.quarkus.component.avro.rpc.it.specific.generated\",\"types\":[{\"type\":\"record\",\"name\":\"Key\",\"fields\":[{\"name\":\"key\",\"type\":\"string\"}]},{\"type\":\"record\",\"name\":\"Value\",\"fields\":[{\"name\":\"value\",\"type\":\"string\"}]}],\"messages\":{\"put\":{\"request\":[{\"name\":\"key\",\"type\":\"Key\"},{\"name\":\"value\",\"type\":\"Value\"}],\"response\":\"null\"},\"get\":{\"request\":[{\"n
 [...]
+
+    /**
+     */
+    void 
put(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key key,
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value value);
+
+    /**
+     */
+    org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value 
get(
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key key);
+
+    @SuppressWarnings("all")
+    public interface Callback extends KeyValueProtocol {
+        public static final org.apache.avro.Protocol PROTOCOL = 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol.PROTOCOL;
+
+        /**
+         * @throws java.io.IOException The async call could not be completed.
+         */
+        void 
put(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key key,
+                
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value value,
+                org.apache.avro.ipc.Callback<java.lang.Void> callback) throws 
java.io.IOException;
+
+        /**
+         * @throws java.io.IOException The async call could not be completed.
+         */
+        void 
get(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key key,
+                
org.apache.avro.ipc.Callback<org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value>
 callback)
+                throws java.io.IOException;
+    }
+}
diff --git 
a/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Value.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Value.java
new file mode 100644
index 0000000..f782458
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/generated/Value.java
@@ -0,0 +1,336 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.camel.quarkus.component.avro.rpc.it.specific.generated;
+
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.SchemaStore;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+
+@org.apache.avro.specific.AvroGenerated
+public class Value extends org.apache.avro.specific.SpecificRecordBase 
implements org.apache.avro.specific.SpecificRecord {
+    private static final long serialVersionUID = 6804416544463210058L;
+    public static final org.apache.avro.Schema SCHEMA$ = new 
org.apache.avro.Schema.Parser().parse(
+            
"{\"type\":\"record\",\"name\":\"Value\",\"namespace\":\"org.apache.camel.quarkus.component.avro.rpc.it.specific.generated\",\"fields\":[{\"name\":\"value\",\"type\":\"string\"}]}");
+
+    public static org.apache.avro.Schema getClassSchema() {
+        return SCHEMA$;
+    }
+
+    private static SpecificData MODEL$ = new SpecificData();
+
+    private static final BinaryMessageEncoder<Value> ENCODER = new 
BinaryMessageEncoder<Value>(MODEL$, SCHEMA$);
+
+    private static final BinaryMessageDecoder<Value> DECODER = new 
BinaryMessageDecoder<Value>(MODEL$, SCHEMA$);
+
+    /**
+     * Return the BinaryMessageEncoder instance used by this class.
+     * 
+     * @return the message encoder used by this class
+     */
+    public static BinaryMessageEncoder<Value> getEncoder() {
+        return ENCODER;
+    }
+
+    /**
+     * Return the BinaryMessageDecoder instance used by this class.
+     * 
+     * @return the message decoder used by this class
+     */
+    public static BinaryMessageDecoder<Value> getDecoder() {
+        return DECODER;
+    }
+
+    /**
+     * Create a new BinaryMessageDecoder instance for this class that uses the 
specified {@link SchemaStore}.
+     * 
+     * @param  resolver a {@link SchemaStore} used to find schemas by 
fingerprint
+     * @return          a BinaryMessageDecoder instance for this class backed 
by the given SchemaStore
+     */
+    public static BinaryMessageDecoder<Value> createDecoder(SchemaStore 
resolver) {
+        return new BinaryMessageDecoder<Value>(MODEL$, SCHEMA$, resolver);
+    }
+
+    /**
+     * Serializes this Value to a ByteBuffer.
+     * 
+     * @return                     a buffer holding the serialized data for 
this instance
+     * @throws java.io.IOException if this instance could not be serialized
+     */
+    public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+        return ENCODER.encode(this);
+    }
+
+    /**
+     * Deserializes a Value from a ByteBuffer.
+     * 
+     * @param  b                   a byte buffer holding serialized data for 
an instance of this class
+     * @return                     a Value instance decoded from the given 
buffer
+     * @throws java.io.IOException if the given bytes could not be 
deserialized into an instance of this class
+     */
+    public static Value fromByteBuffer(
+            java.nio.ByteBuffer b) throws java.io.IOException {
+        return DECODER.decode(b);
+    }
+
+    private java.lang.CharSequence value;
+
+    /**
+     * Default constructor. Note that this does not initialize fields
+     * to their default values from the schema. If that is desired then
+     * one should use <code>newBuilder()</code>.
+     */
+    public Value() {
+    }
+
+    /**
+     * All-args constructor.
+     * 
+     * @param value The new value for value
+     */
+    public Value(java.lang.CharSequence value) {
+        this.value = value;
+    }
+
+    public org.apache.avro.specific.SpecificData getSpecificData() {
+        return MODEL$;
+    }
+
+    public org.apache.avro.Schema getSchema() {
+        return SCHEMA$;
+    }
+
+    // Used by DatumWriter.  Applications should not call.
+    public java.lang.Object get(int field$) {
+        switch (field$) {
+        case 0:
+            return value;
+        default:
+            throw new IndexOutOfBoundsException("Invalid index: " + field$);
+        }
+    }
+
+    // Used by DatumReader.  Applications should not call.
+    @SuppressWarnings(value = "unchecked")
+    public void put(int field$, java.lang.Object value$) {
+        switch (field$) {
+        case 0:
+            value = (java.lang.CharSequence) value$;
+            break;
+        default:
+            throw new IndexOutOfBoundsException("Invalid index: " + field$);
+        }
+    }
+
+    /**
+     * Gets the value of the 'value' field.
+     * 
+     * @return The value of the 'value' field.
+     */
+    public java.lang.CharSequence getValue() {
+        return value;
+    }
+
+    /**
+     * Sets the value of the 'value' field.
+     * 
+     * @param value the value to set.
+     */
+    public void setValue(java.lang.CharSequence value) {
+        this.value = value;
+    }
+
+    /**
+     * Creates a new Value RecordBuilder.
+     * 
+     * @return A new Value RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
newBuilder() {
+        return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder();
+    }
+
+    /**
+     * Creates a new Value RecordBuilder by copying an existing Builder.
+     * 
+     * @param  other The existing builder to copy.
+     * @return       A new Value RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
newBuilder(
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
other) {
+        if (other == null) {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder();
+        } else {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder(other);
+        }
+    }
+
+    /**
+     * Creates a new Value RecordBuilder by copying an existing Value instance.
+     * 
+     * @param  other The existing instance to copy.
+     * @return       A new Value RecordBuilder
+     */
+    public static 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
newBuilder(
+            
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value other) {
+        if (other == null) {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder();
+        } else {
+            return new 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder(other);
+        }
+    }
+
+    /**
+     * RecordBuilder for Value instances.
+     */
+    @org.apache.avro.specific.AvroGenerated
+    public static class Builder extends 
org.apache.avro.specific.SpecificRecordBuilderBase<Value>
+            implements org.apache.avro.data.RecordBuilder<Value> {
+
+        private java.lang.CharSequence value;
+
+        /** Creates a new Builder */
+        private Builder() {
+            super(SCHEMA$);
+        }
+
+        /**
+         * Creates a Builder by copying an existing Builder.
+         * 
+         * @param other The existing Builder to copy.
+         */
+        private 
Builder(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder
 other) {
+            super(other);
+            if (isValidValue(fields()[0], other.value)) {
+                this.value = data().deepCopy(fields()[0].schema(), 
other.value);
+                fieldSetFlags()[0] = other.fieldSetFlags()[0];
+            }
+        }
+
+        /**
+         * Creates a Builder by copying an existing Value instance
+         * 
+         * @param other The existing instance to copy.
+         */
+        private 
Builder(org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value 
other) {
+            super(SCHEMA$);
+            if (isValidValue(fields()[0], other.value)) {
+                this.value = data().deepCopy(fields()[0].schema(), 
other.value);
+                fieldSetFlags()[0] = true;
+            }
+        }
+
+        /**
+         * Gets the value of the 'value' field.
+         * 
+         * @return The value.
+         */
+        public java.lang.CharSequence getValue() {
+            return value;
+        }
+
+        /**
+         * Sets the value of the 'value' field.
+         * 
+         * @param  value The value of 'value'.
+         * @return       This builder.
+         */
+        public 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
setValue(
+                java.lang.CharSequence value) {
+            validate(fields()[0], value);
+            this.value = value;
+            fieldSetFlags()[0] = true;
+            return this;
+        }
+
+        /**
+         * Checks whether the 'value' field has been set.
+         * 
+         * @return True if the 'value' field has been set, false otherwise.
+         */
+        public boolean hasValue() {
+            return fieldSetFlags()[0];
+        }
+
+        /**
+         * Clears the value of the 'value' field.
+         * 
+         * @return This builder.
+         */
+        public 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value.Builder 
clearValue() {
+            value = null;
+            fieldSetFlags()[0] = false;
+            return this;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Value build() {
+            try {
+                Value record = new Value();
+                record.value = fieldSetFlags()[0] ? this.value : 
(java.lang.CharSequence) defaultValue(fields()[0]);
+                return record;
+            } catch (org.apache.avro.AvroMissingFieldException e) {
+                throw e;
+            } catch (java.lang.Exception e) {
+                throw new org.apache.avro.AvroRuntimeException(e);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static final org.apache.avro.io.DatumWriter<Value> WRITER$ = 
(org.apache.avro.io.DatumWriter<Value>) MODEL$
+            .createDatumWriter(SCHEMA$);
+
+    @Override
+    public void writeExternal(java.io.ObjectOutput out)
+            throws java.io.IOException {
+        WRITER$.write(this, SpecificData.getEncoder(out));
+    }
+
+    @SuppressWarnings("unchecked")
+    private static final org.apache.avro.io.DatumReader<Value> READER$ = 
(org.apache.avro.io.DatumReader<Value>) MODEL$
+            .createDatumReader(SCHEMA$);
+
+    @Override
+    public void readExternal(java.io.ObjectInput in)
+            throws java.io.IOException {
+        READER$.read(this, SpecificData.getDecoder(in));
+    }
+
+    @Override
+    protected boolean hasCustomCoders() {
+        return true;
+    }
+
+    @Override
+    public void customEncode(org.apache.avro.io.Encoder out)
+            throws java.io.IOException {
+        out.writeString(this.value);
+
+    }
+
+    @Override
+    public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+            throws java.io.IOException {
+        org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+        if (fieldOrder == null) {
+            this.value = in.readString(this.value instanceof Utf8 ? (Utf8) 
this.value : null);
+
+        } else {
+            for (int i = 0; i < 1; i++) {
+                switch (fieldOrder[i].pos()) {
+                case 0:
+                    this.value = in.readString(this.value instanceof Utf8 ? 
(Utf8) this.value : null);
+                    break;
+
+                default:
+                    throw new java.io.IOException("Corrupt ResolvingDecoder.");
+                }
+            }
+        }
+    }
+}
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/impl/KeyValueProtocolImpl.java
similarity index 52%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/impl/KeyValueProtocolImpl.java
index 52fe2b8..1a1fdd8 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/main/java/org/apache/camel/quarkus/component/avro/rpc/it/specific/impl/KeyValueProtocolImpl.java
@@ -14,17 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it.specific.impl;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import java.util.HashMap;
+import java.util.Map;
 
-@Recorder
-public class AvroRecorder {
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value;
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
+public class KeyValueProtocolImpl implements KeyValueProtocol {
+
+    private Map<Key, Value> store = new HashMap<>();
+
+    @Override
+    public void put(Key key, Value value) {
+        store.put(key, value);
+    }
+
+    @Override
+    public Value get(Key key) {
+        return store.get(key);
+    }
+
+    public Map<Key, Value> getStore() {
+        return store;
     }
 
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpIT.java
similarity index 70%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpIT.java
index 52fe2b8..50db908 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpIT.java
@@ -14,17 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import io.quarkus.test.junit.NativeImageTest;
 
-@Recorder
-public class AvroRecorder {
-
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
-    }
+@NativeImageTest
+class AvroRpcHttpIT extends AvroRpcHttpTest {
 
 }
diff --git 
a/extensions-jvm/avro-rpc/integration-test/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpTest.java
similarity index 71%
rename from 
extensions-jvm/avro-rpc/integration-test/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
rename to 
integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpTest.java
index 346a3c9..d068532 100644
--- 
a/extensions-jvm/avro-rpc/integration-test/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcHttpTest.java
@@ -14,21 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro.it;
+package org.apache.camel.quarkus.component.avro.rpc.it;
 
 import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
 
 @QuarkusTest
-class AvroTest {
+public class AvroRpcHttpTest extends AvroRpcTestSupport {
 
-    @Test
-    public void loadComponentAvro() {
-        /* A simple autogenerated test */
-        RestAssured.get("/avro/load/component/avro")
-                .then()
-                .statusCode(200);
+    public AvroRpcHttpTest() {
+        super(ProtocolType.http);
     }
 
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyIT.java
similarity index 70%
copy from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
copy to 
integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyIT.java
index 52fe2b8..96e4eab 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyIT.java
@@ -14,17 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import io.quarkus.test.junit.NativeImageTest;
 
-@Recorder
-public class AvroRecorder {
-
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
-    }
+@NativeImageTest
+class AvroRpcNettyIT extends AvroRpcNettyTest {
 
 }
diff --git 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyTest.java
similarity index 70%
rename from 
extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
rename to 
integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyTest.java
index 52fe2b8..b5ed7be 100644
--- 
a/extensions-jvm/avro-rpc/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcNettyTest.java
@@ -14,17 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.component.avro;
+package org.apache.camel.quarkus.component.avro.rpc.it;
 
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.component.avro.AvroComponent;
+import io.quarkus.test.junit.QuarkusTest;
 
-@Recorder
-public class AvroRecorder {
+@QuarkusTest
+public class AvroRpcNettyTest extends AvroRpcTestSupport {
 
-    public RuntimeValue<?> createAvroComponent() {
-        return new RuntimeValue<>(new AvroComponent());
+    public AvroRpcNettyTest() {
+        super(ProtocolType.netty);
     }
-
 }
diff --git 
a/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestResource.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestResource.java
new file mode 100644
index 0000000..7e01972
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestResource.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.component.avro.rpc.it;
+
+import java.net.InetSocketAddress;
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.apache.avro.ipc.Server;
+import org.apache.avro.ipc.jetty.HttpServer;
+import org.apache.avro.ipc.netty.NettyServer;
+import org.apache.avro.ipc.reflect.ReflectResponder;
+import org.apache.avro.ipc.specific.SpecificResponder;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestReflection;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.impl.TestReflectionImpl;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.impl.KeyValueProtocolImpl;
+import org.apache.camel.quarkus.test.AvailablePortFinder;
+import org.apache.camel.util.CollectionHelper;
+
+public class AvroRpcTestResource implements 
QuarkusTestResourceLifecycleManager {
+
+    //server implementations
+    TestReflection httpTestReflection = new TestReflectionImpl();
+    TestReflection nettyTestReflection = new TestReflectionImpl();
+    KeyValueProtocolImpl httpKeyValue = new KeyValueProtocolImpl();
+    KeyValueProtocolImpl nettyKeyValue = new KeyValueProtocolImpl();
+
+    //avro servers listening on localhost
+    Server reflectHttpServer, reflectNettyServer, specificHttpServer, 
specificNettyServer;
+
+    @Override
+    public Map<String, String> start() {
+        try {
+
+            // ---------------- producers ---------------
+            final int reflectiveHttpPort = 
AvailablePortFinder.getNextAvailable();
+            reflectHttpServer = new HttpServer(
+                    new ReflectResponder(TestReflection.class, 
httpTestReflection),
+                    reflectiveHttpPort);
+            reflectHttpServer.start();
+
+            final int reflectiveNettyPort = 
AvailablePortFinder.getNextAvailable();
+            reflectNettyServer = new NettyServer(
+                    new ReflectResponder(TestReflection.class, 
nettyTestReflection),
+                    new InetSocketAddress(reflectiveNettyPort));
+            reflectNettyServer.start();
+
+            final int specificHttpPort = 
AvailablePortFinder.getNextAvailable();
+            specificHttpServer = new HttpServer(
+                    new SpecificResponder(KeyValueProtocol.class, 
httpKeyValue),
+                    specificHttpPort);
+            specificHttpServer.start();
+
+            final int specificNettyPort = 
AvailablePortFinder.getNextAvailable();
+            specificNettyServer = new NettyServer(
+                    new SpecificResponder(KeyValueProtocol.class, 
nettyKeyValue),
+                    new InetSocketAddress(specificNettyPort));
+            specificNettyServer.start();
+
+            //----------- consumers ----------------------------------
+
+            final int reflectiveHttpTransceiverPort = 
AvailablePortFinder.getNextAvailable();
+            final int reflectiveNettyTransceiverPort = 
AvailablePortFinder.getNextAvailable();
+            final int specificHttpTransceiverPort = 
AvailablePortFinder.getNextAvailable();
+            final int specificNettyTransceiverPort = 
AvailablePortFinder.getNextAvailable();
+
+            return 
CollectionHelper.mapOf(AvroRpcResource.REFLECTIVE_HTTP_SERVER_PORT_PARAM, 
String.valueOf(reflectiveHttpPort),
+                    AvroRpcResource.REFLECTIVE_NETTY_SERVER_PORT_PARAM, 
String.valueOf(reflectiveNettyPort),
+                    AvroRpcResource.SPECIFIC_HTTP_SERVER_PORT_PARAM, 
String.valueOf(specificHttpPort),
+                    AvroRpcResource.SPECIFIC_NETTY_SERVER_PORT_PARAM, 
String.valueOf(specificNettyPort),
+                    AvroRpcResource.REFLECTIVE_HTTP_TRANSCEIVER_PORT_PARAM, 
String.valueOf(reflectiveHttpTransceiverPort),
+                    AvroRpcResource.REFLECTIVE_NETTY_TRANSCEIVER_PORT_PARAM, 
String.valueOf(reflectiveNettyTransceiverPort),
+                    AvroRpcResource.SPECIFIC_HTTP_TRANSCEIVER_PORT_PARAM, 
String.valueOf(specificHttpTransceiverPort),
+                    AvroRpcResource.SPECIFIC_NETTY_TRANSCEIVER_PORT_PARAM, 
String.valueOf(specificNettyTransceiverPort));
+        } catch (Exception e) {
+            throw new RuntimeException("Could not start avro-rpc server", e);
+        }
+    }
+
+    @Override
+    public void stop() {
+        if (reflectHttpServer != null) {
+            reflectHttpServer.close();
+        }
+        if (reflectNettyServer != null) {
+            reflectNettyServer.close();
+        }
+        if (specificHttpServer != null) {
+            specificHttpServer.close();
+        }
+        if (specificNettyServer != null) {
+            specificNettyServer.close();
+        }
+    }
+
+    @Override
+    public void inject(Object testInstance) {
+        AvroRpcTestSupport testSupport = (AvroRpcTestSupport) testInstance;
+        if (testSupport.isHttp()) {
+            testSupport.setKeyValueProtocol(httpKeyValue);
+            testSupport.setTestReflection(httpTestReflection);
+        } else {
+            testSupport.setKeyValueProtocol(nettyKeyValue);
+            testSupport.setTestReflection(nettyTestReflection);
+        }
+    }
+}
diff --git 
a/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestSupport.java
 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestSupport.java
new file mode 100644
index 0000000..4b97915
--- /dev/null
+++ 
b/integration-tests/avro-rpc/src/test/java/org/apache/camel/quarkus/component/avro/rpc/it/AvroRpcTestSupport.java
@@ -0,0 +1,204 @@
+/*
+ * 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.avro.rpc.it;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URL;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.apache.avro.ipc.HttpTransceiver;
+import org.apache.avro.ipc.Requestor;
+import org.apache.avro.ipc.Transceiver;
+import org.apache.avro.ipc.netty.NettyTransceiver;
+import org.apache.avro.ipc.reflect.ReflectRequestor;
+import org.apache.avro.ipc.specific.SpecificRequestor;
+import org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestPojo;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.reflection.TestReflection;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Key;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.KeyValueProtocol;
+import org.apache.camel.quarkus.component.avro.rpc.it.specific.generated.Value;
+import 
org.apache.camel.quarkus.component.avro.rpc.it.specific.impl.KeyValueProtocolImpl;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@QuarkusTestResource(AvroRpcTestResource.class)
+abstract class AvroRpcTestSupport {
+
+    private final static String NAME = "Sheldon";
+    public static final String NAME_FROM_KEY_VALUE = "{\"value\": \"" + NAME + 
"\"}";
+
+    private TestReflection testReflection;
+
+    private KeyValueProtocol keyValueProtocol;
+
+    private final ProtocolType protocol;
+
+    private Requestor reflectRequestor, specificRequestor;
+    private Transceiver reflectTransceiver, specificTransceiver;
+
+    @Test
+    public void testReflectionProducer() {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam("protocol", protocol)
+                .body(NAME)
+                .post("/avro-rpc/reflectionProducerSet")
+                .then()
+                .statusCode(204);
+
+        assertEquals(NAME, testReflection.getName());
+
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body(protocol)
+                .post("/avro-rpc/reflectionProducerGet")
+                .then()
+                .statusCode(200)
+                .body(is(NAME));
+    }
+
+    @Test
+    public void testSpecificProducer() throws InterruptedException {
+        Key key = Key.newBuilder().setKey("1").build();
+        Value value = Value.newBuilder().setValue(NAME).build();
+
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam("protocol", protocol)
+                .queryParam("key", key.getKey().toString())
+                .body(value.getValue().toString())
+                .post("/avro-rpc/specificProducerPut")
+                .then()
+                .statusCode(204);
+
+        assertEquals(value, ((KeyValueProtocolImpl) 
keyValueProtocol).getStore().get(key));
+
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam("protocol", protocol)
+                .body(key.getKey().toString())
+                .post("/avro-rpc/specificProducerGet")
+                .then()
+                .statusCode(200)
+                .body(is(NAME_FROM_KEY_VALUE));
+    }
+
+    @Test
+    public void testReflectionConsumer() throws Exception {
+        TestPojo testPojo = new TestPojo();
+        testPojo.setPojoName(NAME);
+        Object[] request = { testPojo };
+
+        initReflectRequestor();
+        reflectRequestor.request("setTestPojo", request);
+
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body(protocol)
+                .post("/avro-rpc/reflectionConsumerGet")
+                .then()
+                .statusCode(200)
+                .body(is(NAME));
+    }
+
+    @Test
+    public void testSpecificConsumer() throws Exception {
+        Key key = Key.newBuilder().setKey("2").build();
+        Value value = Value.newBuilder().setValue(NAME).build();
+
+        initSpecificRequestor();
+        specificRequestor.request("put", new Object[] { key, value });
+
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam("protocol", protocol)
+                .body(key.getKey().toString())
+                .post("/avro-rpc/specificConsumerGet")
+                .then()
+                .statusCode(200)
+                .body(is(NAME_FROM_KEY_VALUE));
+    }
+
+    public AvroRpcTestSupport(ProtocolType protocol) {
+        this.protocol = protocol;
+    }
+
+    public void setTestReflection(TestReflection testReflection) {
+        this.testReflection = testReflection;
+    }
+
+    public void setKeyValueProtocol(KeyValueProtocol keyValueProtocol) {
+        this.keyValueProtocol = keyValueProtocol;
+    }
+
+    boolean isHttp() {
+        return ProtocolType.http == protocol;
+    }
+
+    void initReflectRequestor() throws IOException {
+        if (reflectRequestor == null) {
+            if (isHttp()) {
+                reflectTransceiver = new HttpTransceiver(
+                        new URL("http://localhost:";
+                                + 
System.getProperty(AvroRpcResource.REFLECTIVE_HTTP_TRANSCEIVER_PORT_PARAM)));
+            } else {
+                reflectTransceiver = new NettyTransceiver(
+                        new InetSocketAddress("localhost",
+                                
Integer.parseInt(System.getProperty(AvroRpcResource.REFLECTIVE_NETTY_TRANSCEIVER_PORT_PARAM))));
+            }
+            reflectRequestor = new ReflectRequestor(TestReflection.class, 
reflectTransceiver);
+        }
+    }
+
+    void initSpecificRequestor() throws IOException {
+        if (specificRequestor == null) {
+            if (isHttp()) {
+                specificTransceiver = new HttpTransceiver(
+                        new URL("http://localhost:";
+                                + 
System.getProperty(AvroRpcResource.SPECIFIC_HTTP_TRANSCEIVER_PORT_PARAM)));
+            } else {
+                specificTransceiver = new NettyTransceiver(
+                        new InetSocketAddress("localhost",
+                                
Integer.parseInt(System.getProperty(AvroRpcResource.SPECIFIC_NETTY_TRANSCEIVER_PORT_PARAM))));
+            }
+            specificRequestor = new SpecificRequestor(KeyValueProtocol.class, 
specificTransceiver);
+        }
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+
+        if (specificTransceiver != null) {
+            specificTransceiver.close();
+            specificTransceiver = null;
+            specificRequestor = null;
+        }
+
+        if (reflectTransceiver != null) {
+            reflectTransceiver.close();
+            reflectTransceiver = null;
+            reflectRequestor = null;
+        }
+    }
+
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 9f83fb6..f0d273f 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -65,6 +65,7 @@
         <module>arangodb</module>
         <module>as2</module>
         <module>avro</module>
+        <module>avro-rpc</module>
         <module>aws</module>
         <module>aws2</module>
         <module>azure</module>
diff --git a/pom.xml b/pom.xml
index 6afd688..b960306 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,7 @@
         <ahc.version>2.12.1</ahc.version>
         <animal-sniffer.version>1.18</animal-sniffer.version>
         <antlr3.version>3.5.2</antlr3.version><!-- Spark, Stringtemplate and 
probably others -->
+           <avro-ipc-version>1.10.0</avro-ipc-version>
         <awssdk1.version>1.11.714</awssdk1.version>
         <awssdk1-swf-libs.version>1.11.22</awssdk1-swf-libs.version>
         <awssdk2.version>2.14.3</awssdk2.version>
@@ -413,6 +414,7 @@
                         <excludes>
                             <exclude>**/*.adoc</exclude>
                             <exclude>**/*.avsc</exclude>
+                            <exclude>**/*.avpr</exclude>
                             <exclude>**/*.bin</exclude>
                             <exclude>**/*.cnf</exclude>
                             <exclude>**/*.conf</exclude>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 0c95dfc..488bcd2 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -2187,6 +2187,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-avro-rpc-deployment</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-aws-commons</artifactId>
                 <version>${camel-quarkus.version}</version>
             </dependency>
@@ -5497,6 +5502,16 @@
                 <version>${antlr3.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.avro</groupId>
+                <artifactId>avro-ipc-jetty</artifactId>
+                <version>${avro-ipc-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.avro</groupId>
+                <artifactId>avro-ipc-netty</artifactId>
+                <version>${avro-ipc-version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-math3</artifactId>
                 <version>${commons-math3.version}</version>
diff --git a/tooling/scripts/test-categories.yaml 
b/tooling/scripts/test-categories.yaml
index b60127d..d80e1c1 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -122,6 +122,7 @@ misc:
   - kotlin
   - disruptor
 networking2-dataformats:
+  - avro-rpc
   - git
   - mail
   - netty

Reply via email to