You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2021/02/22 20:52:14 UTC

[camel-quarkus] 02/04: Avro: Prefer SyntheticBeanBuildItem to initializing bean producers via volatile fields #2273

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 <pp...@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);