This is an automated email from the ASF dual-hosted git repository. ppalaga pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 06df237ae06b9454c3df69f8a8a244fbab4fc8ca Author: Peter Palaga <ppal...@redhat.com> AuthorDate: Fri Feb 19 21:03:22 2021 +0100 Avro: Prefer SyntheticBeanBuildItem to initializing bean producers via volatile fields #2273 --- .../component/avro/deployment/AvroProcessor.java | 26 +++++++++++++++++----- .../component/avro/AvroDataFormatProducer.java | 10 ++++----- .../camel/quarkus/component/avro/AvroRecorder.java | 12 +++++++--- .../{AvroRecorder.java => AvroSchemaRegistry.java} | 17 +++++++++----- .../component/avro/AvroDataFormatProducerTest.java | 3 ++- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/extensions/avro/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java b/extensions/avro/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java index cba07d8..48604a0 100644 --- a/extensions/avro/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java +++ b/extensions/avro/deployment/src/main/java/org/apache/camel/quarkus/component/avro/deployment/AvroProcessor.java @@ -19,14 +19,17 @@ package org.apache.camel.quarkus.component.avro.deployment; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.inject.Inject; +import javax.inject.Singleton; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem; -import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.processor.AnnotationsTransformer; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -36,11 +39,14 @@ import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.ObjectSubstitutionBuildItem; import io.quarkus.deployment.builditem.ObjectSubstitutionBuildItem.Holder; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.deployment.recording.RecorderContext; +import io.quarkus.runtime.RuntimeValue; import org.apache.avro.Schema; import org.apache.avro.SchemaParseException; import org.apache.avro.generic.GenericContainer; import org.apache.camel.quarkus.component.avro.AvroDataFormatProducer; import org.apache.camel.quarkus.component.avro.AvroRecorder; +import org.apache.camel.quarkus.component.avro.AvroSchemaRegistry; import org.apache.camel.quarkus.component.avro.AvroSchemaSubstitution; import org.apache.camel.quarkus.component.avro.BuildTimeAvroDataFormat; import org.jboss.jandex.AnnotationInstance; @@ -97,24 +103,32 @@ class AvroProcessor { substitutions.produce(new ObjectSubstitutionBuildItem(holder)); } - @Record(ExecutionTime.STATIC_INIT) @BuildStep - void recordAvroSchemasResigtration(BeanArchiveIndexBuildItem beanArchiveIndex, - BeanContainerBuildItem beanContainer, AvroRecorder avroRecorder) { - IndexView index = beanArchiveIndex.getIndex(); + @Record(ExecutionTime.STATIC_INIT) + SyntheticBeanBuildItem avroSchemaRegistry( + RecorderContext ctx, + AvroRecorder recorder, + BeanArchiveIndexBuildItem beanArchiveIndex) { + final RuntimeValue<Map<String, Schema>> schemas = ctx.newInstance(LinkedHashMap.class.getName()); + final IndexView index = beanArchiveIndex.getIndex(); for (AnnotationInstance annotation : index.getAnnotations(BUILD_TIME_AVRO_DATAFORMAT_ANNOTATION)) { String schemaResourceName = annotation.value().asString(); FieldInfo fieldInfo = annotation.target().asField(); String injectedFieldId = fieldInfo.declaringClass().name() + "." + fieldInfo.name(); try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(schemaResourceName)) { Schema avroSchema = new Schema.Parser().parse(is); - avroRecorder.recordAvroSchemaResigtration(beanContainer.getValue(), injectedFieldId, avroSchema); + recorder.addSchema(schemas, injectedFieldId, avroSchema); LOG.debug("Parsed the avro schema at build time from resource named " + schemaResourceName); } catch (SchemaParseException | IOException ex) { final String message = "An issue occured while parsing schema resource on field " + injectedFieldId; throw new RuntimeException(message, ex); } } + + return SyntheticBeanBuildItem.configure(AvroSchemaRegistry.class) + .scope(Singleton.class) + .runtimeValue(recorder.avroSchemaRegistry(schemas)) + .done(); } } diff --git a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducer.java b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducer.java index f5bf922..37582dc 100644 --- a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducer.java +++ b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducer.java @@ -19,8 +19,6 @@ package org.apache.camel.quarkus.component.avro; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; @@ -32,10 +30,10 @@ import org.apache.camel.dataformat.avro.AvroDataFormat; @Singleton public class AvroDataFormatProducer { - private final Map<String, Schema> schemaRegistry = new HashMap<>(); + private final AvroSchemaRegistry schemaRegistry; - public void registerAvroSchema(String injectedFieldId, Schema schema) { - schemaRegistry.put(injectedFieldId, schema); + public AvroDataFormatProducer(AvroSchemaRegistry schemaRegistry) { + this.schemaRegistry = schemaRegistry; } @Produces @@ -45,7 +43,7 @@ public class AvroDataFormatProducer { Field field = (Field) member; if (!Modifier.isStatic(member.getModifiers()) && field.getAnnotation(BuildTimeAvroDataFormat.class) != null) { String injectedFieldId = member.getDeclaringClass().getName() + "." + member.getName(); - Schema schema = schemaRegistry.get(injectedFieldId); + Schema schema = schemaRegistry.getSchema(injectedFieldId); return new AvroDataFormat(schema); } } diff --git a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java index a3b39d1..08562e7 100644 --- a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java +++ b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java @@ -16,15 +16,21 @@ */ package org.apache.camel.quarkus.component.avro; -import io.quarkus.arc.runtime.BeanContainer; +import java.util.Map; + +import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; import org.apache.avro.Schema; @Recorder public class AvroRecorder { - public void recordAvroSchemaResigtration(BeanContainer beanContainer, String injectedFieldId, Schema schema) { - beanContainer.instance(AvroDataFormatProducer.class).registerAvroSchema(injectedFieldId, schema); + public void addSchema(RuntimeValue<Map<String, Schema>> schemas, String injectedFieldId, Schema schema) { + schemas.getValue().put(injectedFieldId, schema); + } + + public RuntimeValue<AvroSchemaRegistry> avroSchemaRegistry(RuntimeValue<Map<String, Schema>> schemas) { + return new RuntimeValue<>(new AvroSchemaRegistry(schemas.getValue())); } } diff --git a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroSchemaRegistry.java similarity index 71% copy from extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java copy to extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroSchemaRegistry.java index a3b39d1..d72a2ff 100644 --- a/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroRecorder.java +++ b/extensions/avro/runtime/src/main/java/org/apache/camel/quarkus/component/avro/AvroSchemaRegistry.java @@ -16,15 +16,20 @@ */ package org.apache.camel.quarkus.component.avro; -import io.quarkus.arc.runtime.BeanContainer; -import io.quarkus.runtime.annotations.Recorder; +import java.util.Map; + import org.apache.avro.Schema; -@Recorder -public class AvroRecorder { +public class AvroSchemaRegistry { + + private final Map<String, Schema> schemaRegistry; + + public AvroSchemaRegistry(Map<String, Schema> schemaRegistry) { + this.schemaRegistry = schemaRegistry; + } - public void recordAvroSchemaResigtration(BeanContainer beanContainer, String injectedFieldId, Schema schema) { - beanContainer.instance(AvroDataFormatProducer.class).registerAvroSchema(injectedFieldId, schema); + public Schema getSchema(String injectedFieldId) { + return schemaRegistry.get(injectedFieldId); } } diff --git a/extensions/avro/runtime/src/test/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducerTest.java b/extensions/avro/runtime/src/test/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducerTest.java index 450ebd0..814defc 100644 --- a/extensions/avro/runtime/src/test/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducerTest.java +++ b/extensions/avro/runtime/src/test/java/org/apache/camel/quarkus/component/avro/AvroDataFormatProducerTest.java @@ -17,6 +17,7 @@ package org.apache.camel.quarkus.component.avro; import java.lang.reflect.Field; +import java.util.Collections; import javax.enterprise.inject.spi.InjectionPoint; @@ -40,7 +41,7 @@ public class AvroDataFormatProducerTest { @BeforeEach public void setup() throws NoSuchFieldException, SecurityException { - instance = new AvroDataFormatProducer(); + instance = new AvroDataFormatProducer(new AvroSchemaRegistry(Collections.emptyMap())); injectedFieldMember = AvroDataFormatProducerTest.class.getDeclaredField("injectedField"); mockInjectionPoint = mock(InjectionPoint.class); when(mockInjectionPoint.getMember()).thenReturn(injectedFieldMember);