Skip to content

Commit 6fd19e0

Browse files
committed
Merge branch '2.19' into tatu/2.18/avro-1.11.4
2 parents d274083 + d12d0c3 commit 6fd19e0

File tree

19 files changed

+162
-63
lines changed

19 files changed

+162
-63
lines changed

.github/workflows/dep_build_v2.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jobs:
1919
env:
2020
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
2121
steps:
22-
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
22+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2323
- name: Set up JDK
24-
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
24+
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
2525
with:
2626
distribution: 'temurin'
2727
java-version: ${{ matrix.java_version }}

.github/workflows/dep_build_v3.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
java_version: ['8', '17', '21']
18+
java_version: ['17', '21']
1919
env:
2020
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
2121
steps:
22-
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
22+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2323
with:
2424
ref: master
2525
- name: Set up JDK
26-
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
26+
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
2727
with:
2828
distribution: 'temurin'
2929
java-version: ${{ matrix.java_version }}

.github/workflows/main.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ on:
44
branches:
55
- master
66
- "3.0"
7-
- "2.18"
7+
- "2.19"
88
paths-ignore:
99
- "README.md"
1010
- "release-notes/*"
1111
pull_request:
1212
branches:
1313
- master
1414
- "3.0"
15-
- "2.18"
15+
- "2.19"
1616
paths-ignore:
1717
- "README.md"
1818
- "release-notes/*"
@@ -21,18 +21,20 @@ permissions:
2121

2222
jobs:
2323
build:
24-
runs-on: ${{ matrix.os }}
24+
runs-on: 'ubuntu-22.04'
2525
strategy:
2626
fail-fast: false
2727
matrix:
2828
java_version: ['8', '11', '17', '21']
29-
os: ['ubuntu-20.04']
29+
include:
30+
- java_version: '8'
31+
release_build: 'R'
3032
env:
3133
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
3234
steps:
33-
- uses: actions/checkout@v4
35+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3436
- name: Set up JDK
35-
uses: actions/setup-java@v4
37+
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
3638
with:
3739
distribution: 'temurin'
3840
java-version: ${{ matrix.java_version }}
@@ -49,18 +51,18 @@ jobs:
4951
id: projectVersion
5052
run: echo "version=$(./mvnw org.apache.maven.plugins:maven-help-plugin:3.3.0:evaluate -DforceStdout -Dexpression=project.version -q)" >> $GITHUB_OUTPUT
5153
- name: Deploy snapshot
52-
if: github.event_name != 'pull_request' && matrix.java_version == '8' && endsWith(steps.projectVersion.outputs.version, '-SNAPSHOT')
54+
if: ${{ matrix.release_build && github.event_name != 'pull_request' && endsWith(steps.projectVersion.outputs.version, '-SNAPSHOT') }}
5355
env:
5456
CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
5557
CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
5658
# MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
5759
run: ./mvnw -B -q -ff -DskipTests -ntp source:jar deploy
5860
- name: Generate code coverage
59-
if: github.event_name != 'pull_request' && matrix.java_version == '8'
61+
if: ${{ matrix.release_build && github.event_name != 'pull_request' }}
6062
run: ./mvnw -B -q -ff -ntp test
6163
- name: Publish code coverage
62-
if: github.event_name != 'pull_request' && matrix.java_version == '8'
63-
uses: codecov/codecov-action@v4
64+
if: ${{ matrix.release_build && github.event_name != 'pull_request' }}
65+
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
6466
with:
6567
token: ${{ secrets.CODECOV_TOKEN }}
6668
file: ./target/site/jacoco/jacoco.xml

.mvn/wrapper/maven-wrapper.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
18-
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
17+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
18+
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ To use these format backends Maven-based projects, use following dependency:
4040

4141
```xml
4242
<dependency>
43-
<groupId>com.fasterxml.jackson.dataformat</groupId>
44-
<artifactId>jackson-dataformat-[FORMAT]</artifactId>
45-
<version>2.13.0</version>
43+
<groupId>com.fasterxml.jackson.dataformat</groupId>
44+
<artifactId>jackson-dataformat-[FORMAT]</artifactId>
45+
<version>2.18.1</version>
4646
</dependency>
4747
```
4848

@@ -66,8 +66,8 @@ responses.
6666
`master` branch is for developing the next major Jackson version -- 3.0 -- but there
6767
are active maintenance branches in which much of development happens:
6868

69-
* `2.14` is for developing the next 2.x version
70-
* `2.13` and `2.12` are for backported fixes for 2.13/2.12 versions (respectively)
69+
* `2.19` is for developing the next 2.x version
70+
* `2.18` and `2.17` are for backported fixes for 2.18/2.17 versions (respectively)
7171

7272
Older branches are usually not changed but are available for historic reasons.
7373
All released versions have matching git tags (`jackson-dataformats-binary-2.10.3`).

avro/README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,32 +114,34 @@ and that's about it, for now.
114114

115115
## Avro Logical Types
116116

117-
Following is an extract from [Logical Types](http://avro.apache.org/docs/current/specification/_print/#logical-types) paragraph in
118-
Avro schema specification:
117+
The following is an excerpt from the [Logical Types](https://avro.apache.org/docs/1.11.1/specification/#logical-types) section of
118+
the Avro schema specification:
119+
119120
> A logical type is an Avro primitive or complex type with extra attributes to represent a derived type. The attribute
120-
> `logicalType` is always be present for a logical type, and is a string with the name of one of the logical types
121-
> defined by Avro specification.
121+
> `logicalType` must always be present for a logical type, and is a string with the name of one of the logical types
122+
> listed later in this section. Other attributes may be defined for particular logical types.
123+
124+
Logical types are supported for a limited set of `java.time` classes and for 'java.util.UUID'. See the table below for more details.
122125

123-
Generation of logical types for limited set of `java.time` classes is supported at the moment. See a table bellow.
126+
### Mapping to Logical Types
124127

125-
### Mapping to Logical Type
128+
Mapping to Avro type and logical type involves these steps:
126129

127-
Mapping to Avro type and logical type works in few steps:
128-
1. Serializer for particular Java type (or class) determines a Jackson type where the Java type will be serialized into.
129-
2. `AvroSchemaGenerator` determines corresponding Avro type for that Jackson type.
130-
2. If logical type generation is enabled, then `logicalType` is determined for the above combination of Java type and
131-
Avro type.
130+
1. The serializer for a Java type identifies the Jackson type it will serialize into.
131+
2. The `AvroSchemaGenerator` maps that Jackson type to the corresponding Avro type.
132+
3. `logicalType` value is combination of Java type and Jackson type.
132133

133134
#### Java type to Avro Logical Type mapping
134135

135-
| Java type | Serialization type | Generated Avro schema with Avro type and logical type
136-
| ----------------------------- | ------------------ | -----------------------------------------------------
137-
| `java.time.OffsetDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}`
138-
| `java.time.ZonedDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}`
139-
| `java.time.Instant` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}`
140-
| `java.time.LocalDate` | NumberType.INT | `{"type": "int", "logicalType": "date"}`
141-
| `java.time.LocalTime` | NumberType.INT | `{"type": "int", "logicalType": "time-millis"}`
142-
| `java.time.LocalDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "local-timestamp-millis"}`
136+
| Java type | Jackson type | Generated Avro schema with logical type |
137+
|----------------------------|-----------------|---------------------------------------------------------------------------------------------------|
138+
| `java.time.OffsetDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}` |
139+
| `java.time.ZonedDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}` |
140+
| `java.time.Instant` | NumberType.LONG | `{"type": "long", "logicalType": "timestamp-millis"}` |
141+
| `java.time.LocalDate` | NumberType.INT | `{"type": "int", "logicalType": "date"}` |
142+
| `java.time.LocalTime` | NumberType.INT | `{"type": "int", "logicalType": "time-millis"}` |
143+
| `java.time.LocalDateTime` | NumberType.LONG | `{"type": "long", "logicalType": "local-timestamp-millis"}` |
144+
| `java.util.UUID` (2.19+) | | `{"type": "fixed", "name": "UUID", "namespace": "java.util", "size": 16, "logicalType" : "uuid"}` |
143145

144146
_Provided Avro logical type generation is enabled._
145147

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/AvroSchemaHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public static Schema createEnumSchema(BeanDescription bean, List<String> values)
286286
* @since 2.11
287287
*/
288288
public static Schema createUUIDSchema() {
289-
return Schema.createFixed("UUID", "", "java.util", 16);
289+
return Schema.createFixed("UUID", null, "java.util", 16);
290290
}
291291

292292
/**

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/StringVisitor.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.fasterxml.jackson.databind.SerializerProvider;
1111
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
1212
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat;
13-
import com.fasterxml.jackson.databind.type.TypeFactory;
1413

1514
public class StringVisitor extends JsonStringFormatVisitor.Base
1615
implements SchemaBuilder
@@ -37,13 +36,10 @@ public void enumTypes(Set<String> enums) {
3736
public Schema builtAvroSchema() {
3837
// Unlike Jackson, Avro treats characters as an int with the java.lang.Character class type.
3938
if (_type.hasRawClass(char.class) || _type.hasRawClass(Character.class)) {
40-
return AvroSchemaHelper.numericAvroSchema(NumberType.INT, TypeFactory.defaultInstance().constructType(Character.class));
41-
}
42-
// [dataformats-binary#179]: need special help with UUIDs, to coerce into Binary
43-
// (could actually be
44-
if (_type.hasRawClass(java.util.UUID.class)) {
45-
return AvroSchemaHelper.createUUIDSchema();
39+
// should we construct JavaType for `Character.class` in case of primitive or... ?
40+
return AvroSchemaHelper.numericAvroSchema(NumberType.INT, _type);
4641
}
42+
4743
BeanDescription bean = _provider.getConfig().introspectClassAnnotations(_type);
4844
Schema schema = Schema.create(Schema.Type.STRING);
4945
// Stringable classes need to include the type
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.fasterxml.jackson.dataformat.avro.schema;
2+
3+
import java.util.Set;
4+
5+
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
6+
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat;
7+
8+
import org.apache.avro.LogicalTypes;
9+
import org.apache.avro.Schema;
10+
11+
/**
12+
* Visitor for {@link java.util.UUID} type. When it is created with logicalTypesEnabled enabled,
13+
* Avro schema is created with logical type uuid.
14+
*
15+
* @since 2.19
16+
*/
17+
public class UUIDVisitor extends JsonStringFormatVisitor.Base
18+
implements SchemaBuilder {
19+
protected boolean _logicalTypesEnabled = false;
20+
21+
22+
public UUIDVisitor(boolean logicalTypesEnabled) {
23+
_logicalTypesEnabled = logicalTypesEnabled;
24+
}
25+
26+
@Override
27+
public void format(JsonValueFormat format) {
28+
// Ideally, we'd recognize UUIDs, Dates etc if need be, here...
29+
}
30+
31+
@Override
32+
public void enumTypes(Set<String> enums) {
33+
// Do nothing
34+
}
35+
36+
@Override
37+
public Schema builtAvroSchema() {
38+
// [dataformats-binary#179]: need special help with UUIDs, to coerce into Binary
39+
// (could actually be
40+
Schema schema = AvroSchemaHelper.createUUIDSchema();
41+
return this._logicalTypesEnabled ? LogicalTypes.uuid().addToSchema(schema) : schema;
42+
}
43+
}

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/VisitorFormatWrapperImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ public JsonStringFormatVisitor expectStringFormat(JavaType type)
214214
return v;
215215
}
216216

217+
if (type.hasRawClass(java.util.UUID.class)) {
218+
UUIDVisitor v = new UUIDVisitor(this._logicalTypesEnabled);
219+
_builder = v;
220+
return v;
221+
}
222+
217223
StringVisitor v = new StringVisitor(_provider, type);
218224
_builder = v;
219225
return v;

0 commit comments

Comments
 (0)