[ 
https://issues.apache.org/jira/browse/AVRO-2840?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Matthew McMahon updated AVRO-2840:
----------------------------------
    Description: 
I was looking for a way to use my Custom Conversion in generated code, but as 
detailed, without the Custom Logical Type being registered in the static 
REGISTERED_TYPES of LogicalTypes, then it will not be considered.

Therefore this issue is an attempt to add this ability into Avro Maven Plugin 
by adding a new configuration map type to the plugin, and will also register 
this logical type in the generated code.

 
{panel:title=Cloned from AVRO-2621}
So, as seen in AVRO-2498 we now have the ability in 1.9, at least using the 
Maven tools, to have generated classes with a field of type UUID. For some 
background, the secret sauce to get this working is:
 * Set the logicalType of the field to 'uuid' and type to 'string'
 * In the maven plugin configuration, add an item to <customConversions> with 
the value org.apache.avro.Conversions$UUIDConversion

I attempted this with a custom type of my own (in this case, joda Money) first 
by implementing a CustomConversion<Money> class that created a new LogicalType 
called "money". This did not work, though, because although the maven mojo 
correctly added the CustomConversion to the SpecificCompiler, when the compiler 
parses the schema and sees the logicalType of type "money", it attempts to look 
up the LogicalType from LogicalTypes the LogicalType is not registered and it 
ignores it, which causes the field within the Schema to not have a logicalType. 
Without a logicalType, the compiler does not consider it a 
"UsedConversionClass" (see SpecificCompiler.getUsedConversionClass()) and they 
velocity template doesn't write the class with the custom field type.

Trying to be clever, I attempted to work around this by putting a static 
initializer in my CustomConversion class which called LogicalTypes.register(). 
Unfortunately for me, the maven plugin doesn't load any of the classes 
specified in <customConversions> until AFTER it has parsed a schema.

Obviously, putting a static initializer inside of a CustomConversion should not 
be part of a solution to this issue, but I propose a very simple solution:
 * Add a logicalTypes property to AbstractAvroMojo, with items of a new type, 
LocalTypeDefinition. That type will have a name and a logicalTypeFactory.
 * Upon startup of the mojo, iterate through each item and call 
LogicalTypes.register() on each, passing the indicated name and a new instance 
of the indicated logicalTypeFactory class.
 * At this point, the existing logic will treat the new custom type the same as 
"uuid" is treated and will generate SpecificRecord classes with fields of that 
type.

I could implement this pretty trivially, if there's an appetite for it. This 
would seem to be 100% backwards compatible.
{panel}

  was:
So, as seen in AVRO-2498 we now have the ability in 1.9, at least using the 
Maven tools, to have generated classes with a field of type UUID. For some 
background, the secret sauce to get this working is:
 * Set the logicalType of the field to 'uuid' and type to 'string'
 * In the maven plugin configuration, add an item to <customConversions> with 
the value org.apache.avro.Conversions$UUIDConversion

I attempted this with a custom type of my own (in this case, joda Money) first 
by implementing a CustomConversion<Money> class that created a new LogicalType 
called "money". This did not work, though, because although the maven mojo 
correctly added the CustomConversion to the SpecificCompiler, when the compiler 
parses the schema and sees the logicalType of type "money", it attempts to look 
up the LogicalType from LogicalTypes the LogicalType is not registered and it 
ignores it, which causes the field within the Schema to not have a logicalType. 
Without a logicalType, the compiler does not consider it a 
"UsedConversionClass" (see SpecificCompiler.getUsedConversionClass()) and they 
velocity template doesn't write the class with the custom field type.

Trying to be clever, I attempted to work around this by putting a static 
initializer in my CustomConversion class which called LogicalTypes.register(). 
Unfortunately for me, the maven plugin doesn't load any of the classes 
specified in <customConversions> until AFTER it has parsed a schema.

Obviously, putting a static initializer inside of a CustomConversion should not 
be part of a solution to this issue, but I propose a very simple solution:
 * Add a logicalTypes property to AbstractAvroMojo, with items of a new type, 
LocalTypeDefinition. That type will have a name and a logicalTypeFactory.
 * Upon startup of the mojo, iterate through each item and call 
LogicalTypes.register() on each, passing the indicated name and a new instance 
of the indicated logicalTypeFactory class.
 * At this point, the existing logic will treat the new custom type the same as 
"uuid" is treated and will generate SpecificRecord classes with fields of that 
type.

I could implement this pretty trivially, if there's an appetite for it. This 
would seem to be 100% backwards compatible.


> Maven allow Custom Logical Types for generated code
> ---------------------------------------------------
>
>                 Key: AVRO-2840
>                 URL: https://issues.apache.org/jira/browse/AVRO-2840
>             Project: Apache Avro
>          Issue Type: Improvement
>          Components: java
>            Reporter: Matthew McMahon
>            Priority: Major
>              Labels: maven
>
> I was looking for a way to use my Custom Conversion in generated code, but as 
> detailed, without the Custom Logical Type being registered in the static 
> REGISTERED_TYPES of LogicalTypes, then it will not be considered.
> Therefore this issue is an attempt to add this ability into Avro Maven Plugin 
> by adding a new configuration map type to the plugin, and will also register 
> this logical type in the generated code.
>  
> {panel:title=Cloned from AVRO-2621}
> So, as seen in AVRO-2498 we now have the ability in 1.9, at least using the 
> Maven tools, to have generated classes with a field of type UUID. For some 
> background, the secret sauce to get this working is:
>  * Set the logicalType of the field to 'uuid' and type to 'string'
>  * In the maven plugin configuration, add an item to <customConversions> with 
> the value org.apache.avro.Conversions$UUIDConversion
> I attempted this with a custom type of my own (in this case, joda Money) 
> first by implementing a CustomConversion<Money> class that created a new 
> LogicalType called "money". This did not work, though, because although the 
> maven mojo correctly added the CustomConversion to the SpecificCompiler, when 
> the compiler parses the schema and sees the logicalType of type "money", it 
> attempts to look up the LogicalType from LogicalTypes the LogicalType is not 
> registered and it ignores it, which causes the field within the Schema to not 
> have a logicalType. Without a logicalType, the compiler does not consider it 
> a "UsedConversionClass" (see SpecificCompiler.getUsedConversionClass()) and 
> they velocity template doesn't write the class with the custom field type.
> Trying to be clever, I attempted to work around this by putting a static 
> initializer in my CustomConversion class which called 
> LogicalTypes.register(). Unfortunately for me, the maven plugin doesn't load 
> any of the classes specified in <customConversions> until AFTER it has parsed 
> a schema.
> Obviously, putting a static initializer inside of a CustomConversion should 
> not be part of a solution to this issue, but I propose a very simple solution:
>  * Add a logicalTypes property to AbstractAvroMojo, with items of a new type, 
> LocalTypeDefinition. That type will have a name and a logicalTypeFactory.
>  * Upon startup of the mojo, iterate through each item and call 
> LogicalTypes.register() on each, passing the indicated name and a new 
> instance of the indicated logicalTypeFactory class.
>  * At this point, the existing logic will treat the new custom type the same 
> as "uuid" is treated and will generate SpecificRecord classes with fields of 
> that type.
> I could implement this pretty trivially, if there's an appetite for it. This 
> would seem to be 100% backwards compatible.
> {panel}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to