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

fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 0a2935765612 Handle java.time* type conversion in Avro Dataformat
0a2935765612 is described below

commit 0a293576561223ad7f01e8e69ce9ee852edda30c
Author: Croway <[email protected]>
AuthorDate: Tue Oct 28 18:58:40 2025 +0100

    Handle java.time* type conversion in Avro Dataformat
---
 .../camel/dataformat/avro/AvroDataFormat.java      |  21 +-
 .../camel/dataformat/avro/SpecificDataNoCache.java |  22 +-
 .../avro/AvroDateMarshalAndUnmarshalTest.java      | 112 ++++++
 .../AvroDateRecordMarshalAndUnmarshalTest.java     | 147 +++++++
 .../camel/dataformat/avro/example/DateRecord.java  | 428 +++++++++++++++++++++
 .../org/apache/camel/dataformat/avro/date.avsc     |  29 ++
 6 files changed, 751 insertions(+), 8 deletions(-)

diff --git 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
index 944235ca3244..ebded0dcd21f 100644
--- 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
+++ 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/AvroDataFormat.java
@@ -138,7 +138,9 @@ public class AvroDataFormat extends ServiceSupport 
implements DataFormat, DataFo
         // the schema should be from the graph class name
         Schema useSchema = actualSchema != null ? actualSchema : 
loadSchema(graph.getClass().getName());
 
-        DatumWriter<Object> datum = new SpecificDatumWriter<>(useSchema);
+        SpecificData specificData = getSpecificData(useSchema);
+
+        DatumWriter<Object> datum = new SpecificDatumWriter<>(useSchema, 
specificData);
         Encoder encoder = EncoderFactory.get().binaryEncoder(outputStream, 
null);
         datum.write(graph, encoder);
         encoder.flush();
@@ -148,17 +150,22 @@ public class AvroDataFormat extends ServiceSupport 
implements DataFormat, DataFo
     public Object unmarshal(Exchange exchange, InputStream inputStream) throws 
Exception {
         ObjectHelper.notNull(actualSchema, "schema", this);
 
-        ClassLoader classLoader = null;
-        Class<?> clazz = 
camelContext.getClassResolver().resolveClass(actualSchema.getFullName());
+        SpecificData specificData = getSpecificData(actualSchema);
+        DatumReader<GenericRecord> reader = new SpecificDatumReader<>(null, 
null, specificData);
+        reader.setSchema(actualSchema);
+        Decoder decoder = DecoderFactory.get().binaryDecoder(inputStream, 
null);
+        return reader.read(null, decoder);
+    }
 
+    private SpecificData getSpecificData(Schema schema) {
+        // Use SpecificDataNoCache to support logical type conversions (date, 
timestamp, UUID, decimal, etc.)
+        ClassLoader classLoader = null;
+        Class<?> clazz = 
camelContext.getClassResolver().resolveClass(schema.getFullName());
         if (clazz != null) {
             classLoader = clazz.getClassLoader();
         }
         SpecificData specificData = new SpecificDataNoCache(classLoader);
-        DatumReader<GenericRecord> reader = new SpecificDatumReader<>(null, 
null, specificData);
-        reader.setSchema(actualSchema);
-        Decoder decoder = DecoderFactory.get().binaryDecoder(inputStream, 
null);
-        return reader.read(null, decoder);
+        return specificData;
     }
 
 }
diff --git 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/SpecificDataNoCache.java
 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/SpecificDataNoCache.java
index 92a3d92312f6..30748226353e 100644
--- 
a/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/SpecificDataNoCache.java
+++ 
b/components/camel-avro/src/main/java/org/apache/camel/dataformat/avro/SpecificDataNoCache.java
@@ -17,20 +17,40 @@
 package org.apache.camel.dataformat.avro;
 
 import org.apache.avro.Schema;
+import org.apache.avro.data.TimeConversions;
 import org.apache.avro.specific.SpecificData;
 
 public class SpecificDataNoCache extends SpecificData {
 
     public SpecificDataNoCache() {
+        super();
+        addLogicalTypeConversions();
     }
 
     public SpecificDataNoCache(ClassLoader classLoader) {
         super(classLoader);
+        addLogicalTypeConversions();
+    }
+
+    private void addLogicalTypeConversions() {
+        addLogicalTypeConversion(new TimeConversions.DateConversion());
+        addLogicalTypeConversion(new TimeConversions.TimeMillisConversion());
+        addLogicalTypeConversion(new TimeConversions.TimeMicrosConversion());
+        addLogicalTypeConversion(new 
TimeConversions.TimestampMillisConversion());
+        addLogicalTypeConversion(new 
TimeConversions.TimestampMicrosConversion());
+        addLogicalTypeConversion(new 
TimeConversions.TimestampNanosConversion());
+        addLogicalTypeConversion(new 
TimeConversions.LocalTimestampMillisConversion());
+        addLogicalTypeConversion(new 
TimeConversions.LocalTimestampMicrosConversion());
+        addLogicalTypeConversion(new 
TimeConversions.LocalTimestampNanosConversion());
+
+        addLogicalTypeConversion(new 
org.apache.avro.Conversions.UUIDConversion());
+
+        addLogicalTypeConversion(new 
org.apache.avro.Conversions.DecimalConversion());
     }
 
     @Override
     public Object newRecord(Object old, Schema schema) {
-        Class c = new SpecificDataNoCache().getClass(schema);
+        Class<?> c = this.getClass(schema);
         return c == null ? super.newRecord(old, schema) : (c.isInstance(old) ? 
old : newInstance(c, schema));
     }
 
diff --git 
a/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateMarshalAndUnmarshalTest.java
 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateMarshalAndUnmarshalTest.java
new file mode 100644
index 000000000000..626553ba9020
--- /dev/null
+++ 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateMarshalAndUnmarshalTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.dataformat.avro;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.Instant;
+import java.time.LocalDate;
+
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.generic.GenericRecord;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class AvroDateMarshalAndUnmarshalTest extends CamelTestSupport {
+
+    private Schema schema;
+
+    @Override
+    public void doPreSetup() throws Exception {
+        schema = getSchema();
+    }
+
+    @Test
+    public void testDateMarshalAndUnmarshal() throws InterruptedException {
+        marshalAndUnmarshalDate("direct:in", "direct:back");
+    }
+
+    @Test
+    public void testDateWithNullValues() throws InterruptedException {
+        GenericRecord input = new GenericData.Record(schema);
+        input.put("date", null);
+        input.put("timestamp", null);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(GenericRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        GenericRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(GenericRecord.class);
+        assertEquals(input.get("date"), output.get("date"));
+        assertEquals(input.get("timestamp"), output.get("timestamp"));
+    }
+
+    private void marshalAndUnmarshalDate(String inURI, String outURI) throws 
InterruptedException {
+        GenericRecord input = new GenericData.Record(schema);
+
+        // Avro date logical type - use LocalDate directly
+        LocalDate date = LocalDate.of(2025, 10, 28);
+        input.put("date", date);
+
+        // Avro timestamp-millis logical type - use Instant directly
+        Instant timestamp = Instant.ofEpochMilli(1730000000000L); // Fixed 
timestamp for consistent testing
+        input.put("timestamp", timestamp);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(GenericRecord.class);
+
+        Object marshalled = template.requestBody(inURI, input);
+        template.sendBody(outURI, marshalled);
+        mock.assertIsSatisfied();
+
+        GenericRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(GenericRecord.class);
+        // The logical type conversions ensure date and timestamp are 
converted back to LocalDate and Instant
+        assertEquals(date, output.get("date"));
+        assertEquals(timestamp, output.get("timestamp"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                AvroDataFormat format = new AvroDataFormat(schema);
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+            }
+        };
+    }
+
+    private Schema getSchema() throws IOException {
+        String schemaLocation = getClass().getResource("date.avsc").getFile();
+        File schemaFile = new File(schemaLocation);
+        assertTrue(schemaFile.exists());
+        return new Schema.Parser().parse(schemaFile);
+    }
+}
diff --git 
a/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateRecordMarshalAndUnmarshalTest.java
 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateRecordMarshalAndUnmarshalTest.java
new file mode 100644
index 000000000000..3ce376faedd9
--- /dev/null
+++ 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/AvroDateRecordMarshalAndUnmarshalTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.dataformat.avro;
+
+import java.time.Instant;
+import java.time.LocalDate;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.avro.example.DateRecord;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class AvroDateRecordMarshalAndUnmarshalTest extends CamelTestSupport {
+
+    @Test
+    public void testDateRecordMarshalAndUnmarshal() throws 
InterruptedException {
+        LocalDate date = LocalDate.of(2025, 10, 28);
+        Instant timestamp = Instant.parse("2024-01-15T10:30:00Z");
+
+        DateRecord input = new DateRecord(date, timestamp);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DateRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        DateRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(DateRecord.class);
+        assertNotNull(output);
+        assertEquals(date, output.getDate());
+        assertEquals(timestamp, output.getTimestamp());
+    }
+
+    @Test
+    public void testDateRecordWithNullValues() throws InterruptedException {
+        DateRecord input = new DateRecord(null, null);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DateRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        DateRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(DateRecord.class);
+        assertNotNull(output);
+        assertNull(output.getDate());
+        assertNull(output.getTimestamp());
+    }
+
+    @Test
+    public void testDateRecordWithBuilder() throws InterruptedException {
+        LocalDate date = LocalDate.of(2024, 1, 15);
+        Instant timestamp = Instant.parse("2024-01-15T10:30:00Z");
+
+        DateRecord input = DateRecord.newBuilder()
+                .setDate(date)
+                .setTimestamp(timestamp)
+                .build();
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DateRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        DateRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(DateRecord.class);
+        assertNotNull(output);
+        assertEquals(date, output.getDate());
+        assertEquals(timestamp, output.getTimestamp());
+    }
+
+    @Test
+    public void testDateRecordWithOnlyDate() throws InterruptedException {
+        LocalDate date = LocalDate.of(2025, 12, 25);
+        DateRecord input = new DateRecord(date, null);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DateRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        DateRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(DateRecord.class);
+        assertNotNull(output);
+        assertEquals(date, output.getDate());
+        assertNull(output.getTimestamp());
+    }
+
+    @Test
+    public void testDateRecordWithOnlyTimestamp() throws InterruptedException {
+        Instant timestamp = Instant.parse("2024-01-15T10:30:00Z");
+        DateRecord input = new DateRecord(null, timestamp);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DateRecord.class);
+
+        Object marshalled = template.requestBody("direct:in", input);
+        template.sendBody("direct:back", marshalled);
+        mock.assertIsSatisfied();
+
+        DateRecord output = 
mock.getReceivedExchanges().get(0).getIn().getBody(DateRecord.class);
+        assertNotNull(output);
+        assertNull(output.getDate());
+        assertEquals(timestamp, output.getTimestamp());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                AvroDataFormat format = new AvroDataFormat(DateRecord.SCHEMA$);
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/example/DateRecord.java
 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/example/DateRecord.java
new file mode 100644
index 000000000000..5aa631103dee
--- /dev/null
+++ 
b/components/camel-avro/src/test/java/org/apache/camel/dataformat/avro/example/DateRecord.java
@@ -0,0 +1,428 @@
+/*
+ * 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.
+ */
+/*
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package org.apache.camel.dataformat.avro.example;
+
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.SchemaStore;
+import org.apache.avro.specific.SpecificData;
+
[email protected]
+public class DateRecord extends org.apache.avro.specific.SpecificRecordBase 
implements org.apache.avro.specific.SpecificRecord {
+    private static final long serialVersionUID = 8653491882695437570L;
+
+    public static final org.apache.avro.Schema SCHEMA$ = new 
org.apache.avro.Schema.Parser().parse(
+            
"{\"type\":\"record\",\"name\":\"DateRecord\",\"namespace\":\"org.apache.camel.dataformat.avro.example\",\"fields\":[{\"name\":\"date\",\"type\":[\"null\",{\"type\":\"int\",\"logicalType\":\"date\"}],\"default\":null},{\"name\":\"timestamp\",\"type\":[\"null\",{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}],\"default\":null}]}");
+
+    public static org.apache.avro.Schema getClassSchema() {
+        return SCHEMA$;
+    }
+
+    private static final SpecificData MODEL$ = new SpecificData();
+    static {
+        MODEL$.addLogicalTypeConversion(new 
org.apache.avro.data.TimeConversions.DateConversion());
+        MODEL$.addLogicalTypeConversion(new 
org.apache.avro.data.TimeConversions.TimestampMillisConversion());
+    }
+
+    private static final BinaryMessageEncoder<DateRecord> ENCODER = new 
BinaryMessageEncoder<>(MODEL$, SCHEMA$);
+
+    private static final BinaryMessageDecoder<DateRecord> DECODER = new 
BinaryMessageDecoder<>(MODEL$, SCHEMA$);
+
+    /**
+     * Return the BinaryMessageEncoder instance used by this class.
+     *
+     * @return the message encoder used by this class
+     */
+    public static BinaryMessageEncoder<DateRecord> getEncoder() {
+        return ENCODER;
+    }
+
+    /**
+     * Return the BinaryMessageDecoder instance used by this class.
+     *
+     * @return the message decoder used by this class
+     */
+    public static BinaryMessageDecoder<DateRecord> 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<DateRecord> createDecoder(SchemaStore 
resolver) {
+        return new BinaryMessageDecoder<>(MODEL$, SCHEMA$, resolver);
+    }
+
+    /**
+     * Serializes this DateRecord 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 DateRecord from a ByteBuffer.
+     *
+     * @param  b                   a byte buffer holding serialized data for 
an instance of this class
+     * @return                     a DateRecord 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 DateRecord fromByteBuffer(
+            java.nio.ByteBuffer b)
+            throws java.io.IOException {
+        return DECODER.decode(b);
+    }
+
+    private java.time.LocalDate date;
+    private java.time.Instant timestamp;
+
+    /**
+     * 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 DateRecord() {
+    }
+
+    /**
+     * All-args constructor.
+     *
+     * @param date      The new value for date
+     * @param timestamp The new value for timestamp
+     */
+    public DateRecord(java.time.LocalDate date, java.time.Instant timestamp) {
+        this.date = date;
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public SpecificData getSpecificData() {
+        return MODEL$;
+    }
+
+    @Override
+    public org.apache.avro.Schema getSchema() {
+        return SCHEMA$;
+    }
+
+    // Used by DatumWriter.  Applications should not call.
+    @Override
+    public Object get(int field$) {
+        switch (field$) {
+            case 0:
+                return date;
+            case 1:
+                return timestamp;
+            default:
+                throw new IndexOutOfBoundsException("Invalid index: " + 
field$);
+        }
+    }
+
+    // Used by DatumReader.  Applications should not call.
+    @Override
+    @SuppressWarnings(value = "unchecked")
+    public void put(int field$, Object value$) {
+        switch (field$) {
+            case 0:
+                date = (java.time.LocalDate) value$;
+                break;
+            case 1:
+                timestamp = (java.time.Instant) value$;
+                break;
+            default:
+                throw new IndexOutOfBoundsException("Invalid index: " + 
field$);
+        }
+    }
+
+    /**
+     * Gets the value of the 'date' field.
+     *
+     * @return The value of the 'date' field.
+     */
+    public java.time.LocalDate getDate() {
+        return date;
+    }
+
+    /**
+     * Sets the value of the 'date' field.
+     *
+     * @param value the value to set.
+     */
+    public void setDate(java.time.LocalDate value) {
+        this.date = value;
+    }
+
+    /**
+     * Gets the value of the 'timestamp' field.
+     *
+     * @return The value of the 'timestamp' field.
+     */
+    public java.time.Instant getTimestamp() {
+        return timestamp;
+    }
+
+    /**
+     * Sets the value of the 'timestamp' field.
+     *
+     * @param value the value to set.
+     */
+    public void setTimestamp(java.time.Instant value) {
+        this.timestamp = value;
+    }
+
+    /**
+     * Creates a new DateRecord RecordBuilder.
+     *
+     * @return A new DateRecord RecordBuilder
+     */
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Creates a new DateRecord RecordBuilder by copying an existing Builder.
+     *
+     * @param  other The existing builder to copy.
+     * @return       A new DateRecord RecordBuilder
+     */
+    public static Builder newBuilder(Builder other) {
+        if (other == null) {
+            return new Builder();
+        } else {
+            return new Builder(other);
+        }
+    }
+
+    /**
+     * Creates a new DateRecord RecordBuilder by copying an existing 
DateRecord instance.
+     *
+     * @param  other The existing instance to copy.
+     * @return       A new DateRecord RecordBuilder
+     */
+    public static Builder newBuilder(DateRecord other) {
+        if (other == null) {
+            return new Builder();
+        } else {
+            return new 
org.apache.camel.dataformat.avro.example.DateRecord.Builder(other);
+        }
+    }
+
+    /**
+     * RecordBuilder for DateRecord instances.
+     */
+    @org.apache.avro.specific.AvroGenerated
+    public static class Builder extends 
org.apache.avro.specific.SpecificRecordBuilderBase<DateRecord>
+            implements org.apache.avro.data.RecordBuilder<DateRecord> {
+
+        private java.time.LocalDate date;
+        private java.time.Instant timestamp;
+
+        /** Creates a new Builder */
+        private Builder() {
+            super(SCHEMA$, MODEL$);
+        }
+
+        /**
+         * Creates a Builder by copying an existing Builder.
+         *
+         * @param other The existing Builder to copy.
+         */
+        private 
Builder(org.apache.camel.dataformat.avro.example.DateRecord.Builder other) {
+            super(other);
+            if (isValidValue(fields()[0], other.date)) {
+                this.date = data().deepCopy(fields()[0].schema(), other.date);
+                fieldSetFlags()[0] = other.fieldSetFlags()[0];
+            }
+            if (isValidValue(fields()[1], other.timestamp)) {
+                this.timestamp = data().deepCopy(fields()[1].schema(), 
other.timestamp);
+                fieldSetFlags()[1] = other.fieldSetFlags()[1];
+            }
+        }
+
+        /**
+         * Creates a Builder by copying an existing DateRecord instance
+         *
+         * @param other The existing instance to copy.
+         */
+        private Builder(org.apache.camel.dataformat.avro.example.DateRecord 
other) {
+            super(SCHEMA$, MODEL$);
+            if (isValidValue(fields()[0], other.date)) {
+                this.date = data().deepCopy(fields()[0].schema(), other.date);
+                fieldSetFlags()[0] = true;
+            }
+            if (isValidValue(fields()[1], other.timestamp)) {
+                this.timestamp = data().deepCopy(fields()[1].schema(), 
other.timestamp);
+                fieldSetFlags()[1] = true;
+            }
+        }
+
+        /**
+         * Gets the value of the 'date' field.
+         *
+         * @return The value.
+         */
+        public java.time.LocalDate getDate() {
+            return date;
+        }
+
+        /**
+         * Sets the value of the 'date' field.
+         *
+         * @param  value The value of 'date'.
+         * @return       This builder.
+         */
+        public org.apache.camel.dataformat.avro.example.DateRecord.Builder 
setDate(java.time.LocalDate value) {
+            validate(fields()[0], value);
+            this.date = value;
+            fieldSetFlags()[0] = true;
+            return this;
+        }
+
+        /**
+         * Checks whether the 'date' field has been set.
+         *
+         * @return True if the 'date' field has been set, false otherwise.
+         */
+        public boolean hasDate() {
+            return fieldSetFlags()[0];
+        }
+
+        /**
+         * Clears the value of the 'date' field.
+         *
+         * @return This builder.
+         */
+        public org.apache.camel.dataformat.avro.example.DateRecord.Builder 
clearDate() {
+            date = null;
+            fieldSetFlags()[0] = false;
+            return this;
+        }
+
+        /**
+         * Gets the value of the 'timestamp' field.
+         *
+         * @return The value.
+         */
+        public java.time.Instant getTimestamp() {
+            return timestamp;
+        }
+
+        /**
+         * Sets the value of the 'timestamp' field.
+         *
+         * @param  value The value of 'timestamp'.
+         * @return       This builder.
+         */
+        public org.apache.camel.dataformat.avro.example.DateRecord.Builder 
setTimestamp(java.time.Instant value) {
+            validate(fields()[1], value);
+            this.timestamp = value;
+            fieldSetFlags()[1] = true;
+            return this;
+        }
+
+        /**
+         * Checks whether the 'timestamp' field has been set.
+         *
+         * @return True if the 'timestamp' field has been set, false otherwise.
+         */
+        public boolean hasTimestamp() {
+            return fieldSetFlags()[1];
+        }
+
+        /**
+         * Clears the value of the 'timestamp' field.
+         *
+         * @return This builder.
+         */
+        public org.apache.camel.dataformat.avro.example.DateRecord.Builder 
clearTimestamp() {
+            timestamp = null;
+            fieldSetFlags()[1] = false;
+            return this;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public DateRecord build() {
+            try {
+                DateRecord record = new DateRecord();
+                record.date = fieldSetFlags()[0] ? this.date : 
(java.time.LocalDate) defaultValue(fields()[0]);
+                record.timestamp = fieldSetFlags()[1] ? this.timestamp : 
(java.time.Instant) defaultValue(fields()[1]);
+                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<DateRecord> WRITER$
+            = (org.apache.avro.io.DatumWriter<DateRecord>) 
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<DateRecord> READER$
+            = (org.apache.avro.io.DatumReader<DateRecord>) 
MODEL$.createDatumReader(SCHEMA$);
+
+    @Override
+    public void readExternal(java.io.ObjectInput in)
+            throws java.io.IOException {
+        READER$.read(this, SpecificData.getDecoder(in));
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        result = 31 * result + (date == null ? 0 : date.hashCode());
+        result = 31 * result + (timestamp == null ? 0 : timestamp.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DateRecord)) {
+            return false;
+        }
+        DateRecord other = (DateRecord) o;
+        if (!java.util.Objects.equals(this.date, other.date)) {
+            return false;
+        }
+        if (!java.util.Objects.equals(this.timestamp, other.timestamp)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git 
a/components/camel-avro/src/test/resources/org/apache/camel/dataformat/avro/date.avsc
 
b/components/camel-avro/src/test/resources/org/apache/camel/dataformat/avro/date.avsc
new file mode 100644
index 000000000000..d2fbf7ddef25
--- /dev/null
+++ 
b/components/camel-avro/src/test/resources/org/apache/camel/dataformat/avro/date.avsc
@@ -0,0 +1,29 @@
+{
+  "type": "record",
+  "name": "DateRecord",
+  "namespace": "org.apache.camel.dataformat.avro.example",
+  "fields": [
+    {
+      "name": "date",
+      "type": [
+        "null",
+        {
+          "type": "int",
+          "logicalType": "date"
+        }
+      ],
+      "default": null
+    },
+    {
+      "name": "timestamp",
+      "type": [
+        "null",
+        {
+          "type": "long",
+          "logicalType": "timestamp-millis"
+        }
+      ],
+      "default": null
+    }
+  ]
+}
\ No newline at end of file

Reply via email to