fmiguelez opened a new issue, #15858:
URL: https://github.com/apache/pulsar/issues/15858

   
   **Describe the bug**
   When JSR310 is enabled in `SchemaDefintionBuilder` the 
`TimestampMillisConversion` is registered for `java.time.Instant` (using 
logical type `timestamp-millis`), however that conversion is never applied as 
`TimestampMicrosConversion` is also registered first (i.e. with higher 
priority) inside `AvroSchema` class of Pulsar client.
   
   E.g. take this POJO definition:
   
   ```
   public class TestObject
   {
     private Instant startTimestamp;
     public Instant getStartTimestamp() { return startTimestamp; }
     public void setStartTimestamp(Instant startTimestamp) { 
this.startTimestamp = startTimestamp; }
   }
   ```
   
   Consider these two ways of obtaining AVRO schema from POJO:
   
   ```
       Schema<TestObject> schema = Schema.AVRO(TestObject.class);
       Schema<TestObject> schema = 
AvroSchema.of(SchemaDefinition.<T>builder().withPojo(TestObject.class).withJSR310ConversionEnabled(true).build());
   ```
   
   These two methods produce same AVRO type for field `startTimestamp` (`union` 
with `null` has been omited for clarity): 
   ```
      {"type":"long","logicalType":"timestamp-micros"}
   ```
   
   Second method should however produce following type (**`timestamp-millis`** 
instead of **`timestamp-micros`**):
   ```
      {"type":"long","logicalType":"timestamp-millis"}
   ```
   
   If we look at `AvroSchema.addLogicalTypeConversions()` we can spot the BUG:  
  
   
   ```
   public static void addLogicalTypeConversions(ReflectData reflectData, 
boolean jsr310ConversionEnabled, boolean decimalConversionEnabled) {
           if (decimalConversionEnabled) {
               reflectData.addLogicalTypeConversion(new DecimalConversion());
           }
   
           reflectData.addLogicalTypeConversion(new DateConversion());
           reflectData.addLogicalTypeConversion(new TimeMillisConversion());
           reflectData.addLogicalTypeConversion(new TimeMicrosConversion());
           reflectData.addLogicalTypeConversion(new 
TimestampMicrosConversion());
           if (jsr310ConversionEnabled) {
               // This registration has no effect as TimestampMicrosConversion 
is 
               // registered first and always takes precedence
               reflectData.addLogicalTypeConversion(new 
TimestampMillisConversion());
           } else {
               try {
                   Class.forName("org.joda.time.DateTime");
                   reflectData.addLogicalTypeConversion(new 
AvroSchema.TimestampConversion());
               } catch (ClassNotFoundException var4) {
               }
           }
   
           reflectData.addLogicalTypeConversion(new UUIDConversion());
       }
   ```
   
   One fix could be the following:
   
   ```
   public static void addLogicalTypeConversions(ReflectData reflectData, 
boolean jsr310ConversionEnabled, boolean decimalConversionEnabled) {
           if (decimalConversionEnabled) {
               reflectData.addLogicalTypeConversion(new DecimalConversion());
           }
   
           reflectData.addLogicalTypeConversion(new DateConversion());
           reflectData.addLogicalTypeConversion(new TimeMillisConversion());
           reflectData.addLogicalTypeConversion(new TimeMicrosConversion());
           if (jsr310ConversionEnabled) {
               reflectData.addLogicalTypeConversion(new 
TimestampMillisConversion());
           } else {
               // Register alternative conversion to micros if JSR310 is not 
enabled
               reflectData.addLogicalTypeConversion(new 
TimestampMicrosConversion());
               try {
                   Class.forName("org.joda.time.DateTime");
                   reflectData.addLogicalTypeConversion(new 
AvroSchema.TimestampConversion());
               } catch (ClassNotFoundException var4) {
               }
           }
   
           reflectData.addLogicalTypeConversion(new UUIDConversion());
       }
   ```
   **To Reproduce**
   Already indicated in the description.
   
   **Expected behavior**
   When JSR310 flag is enabled interpret use logical type `timestamp-millis` 
instead of `timestamp-micros` in AVRO Schema for  `java.time.Instant` types.
   
   **Screenshots**
   None
   
   **Desktop (please complete the following information):**
   NA
   
   **Additional context**
   Affects all versions since **2.5.1**
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to