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