1 /***********************************************************************
2  * Copyright (c) 2013-2025 General Atomics Integrated Intelligence, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Apache License, Version 2.0
5  * which accompanies this distribution and is available at
6  * https://www.apache.org/licenses/LICENSE-2.0
7  ***********************************************************************/
8 
9 package org.locationtech.geomesa.features.avro.io
10 
11 import org.apache.avro.file.{DataFileStream, DataFileWriter}
12 import org.geotools.api.feature.simple.{SimpleFeature, SimpleFeatureType}
13 import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes
14 
15 object AvroDataFile extends AvroDataFile
16 
17 /**
18   * AvroDataFiles are binary Avro files (see https://avro.apache.org/) that encode
19   * SimpleFeatures using a custom avro schema per SimpleFeatureType. AvroDataFiles
20   * are meant to:
21   * 1. Provide binary longer-term storage in filesystems for SimpleFeatures
22   * 2. Carry the SimpleFeatureType and feature name along with the data
23   *    using avro metadata
24   * 3. Be self-describing outside of Geotools as much as possible
25   *
26   * You may want to consider gzipping your avro data file for better compression
27   *
28   * Version 3 supports Bytes as a type in the SFT
29   */
30 trait AvroDataFile {
31 
32   val SftNameKey = "sft.name"
33   val SftSpecKey = "sft.spec"
34   val VersionKey = "version"
35 
36   private[avro] val Version: Long = 3L
37 
38   def setMetaData(dfw: DataFileWriter[SimpleFeature], sft: SimpleFeatureType): Unit = {
39     dfw.setMeta(VersionKey, Version)
40     dfw.setMeta(SftNameKey, sft.getTypeName)
41     dfw.setMeta(SftSpecKey, SimpleFeatureTypes.encodeType(sft))
42   }
43 
44   /**
45     * Backwards compatible...Version 2 can parse v1
46     *
47     * @param dfs data file stream
48     * @return
49     */
50   def canParse(dfs: DataFileStream[_]): Boolean = {
51     dfs.getMetaKeys.contains(VersionKey) &&
52       dfs.getMetaLong(VersionKey) <= Version &&
53       dfs.getMetaString(SftNameKey) != null &&
54       dfs.getMetaString(SftSpecKey) != null
55   }
56 
57   def getSft(dfs: DataFileStream[_]): SimpleFeatureType = {
58     val sftName = dfs.getMetaString(SftNameKey)
59     val sftString = dfs.getMetaString(SftSpecKey)
60     SimpleFeatureTypes.createType(sftName, sftString)
61   }
62 }
Line Stmt Id Pos Tree Symbol Tests Code
32 119 1377 - 1387 Literal <nosymbol> "sft.name"
33 120 1407 - 1417 Literal <nosymbol> "sft.spec"
34 121 1437 - 1446 Literal <nosymbol> "version"
36 122 1484 - 1486 Literal <nosymbol> 3L
39 123 1592 - 1602 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.VersionKey AvroDataFile.this.VersionKey
39 124 1604 - 1611 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.Version AvroDataFile.this.Version
39 125 1580 - 1612 Apply org.apache.avro.file.DataFileWriter.setMeta dfw.setMeta(AvroDataFile.this.VersionKey, AvroDataFile.this.Version)
40 126 1629 - 1639 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.SftNameKey AvroDataFile.this.SftNameKey
40 127 1641 - 1656 Apply org.geotools.api.feature.simple.SimpleFeatureType.getTypeName sft.getTypeName()
40 128 1617 - 1657 Apply org.apache.avro.file.DataFileWriter.setMeta dfw.setMeta(AvroDataFile.this.SftNameKey, sft.getTypeName())
41 129 1674 - 1684 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.SftSpecKey AvroDataFile.this.SftSpecKey
41 130 1686 - 1720 Apply org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes.encodeType org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes.encodeType(sft)
41 131 1662 - 1721 Apply org.apache.avro.file.DataFileWriter.setMeta dfw.setMeta(AvroDataFile.this.SftSpecKey, org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes.encodeType(sft))
41 132 1673 - 1673 Literal <nosymbol> ()
51 133 1927 - 1937 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.VersionKey AvroDataFile.this.VersionKey
52 134 1964 - 1974 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.VersionKey AvroDataFile.this.VersionKey
52 135 1979 - 1986 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.Version AvroDataFile.this.Version
52 136 1948 - 1986 Apply scala.Long.<= dfs.getMetaLong(AvroDataFile.this.VersionKey).<=(AvroDataFile.this.Version)
53 137 1996 - 2033 Apply java.lang.Object.!= dfs.getMetaString(AvroDataFile.this.SftNameKey).!=(null)
53 139 1902 - 2080 Apply scala.Boolean.&& dfs.getMetaKeys().contains(AvroDataFile.this.VersionKey).&&(dfs.getMetaLong(AvroDataFile.this.VersionKey).<=(AvroDataFile.this.Version)).&&(dfs.getMetaString(AvroDataFile.this.SftNameKey).!=(null)).&&(dfs.getMetaString(AvroDataFile.this.SftSpecKey).!=(null))
54 138 2043 - 2080 Apply java.lang.Object.!= dfs.getMetaString(AvroDataFile.this.SftSpecKey).!=(null)
58 140 2182 - 2192 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.SftNameKey AvroDataFile.this.SftNameKey
58 141 2164 - 2193 Apply org.apache.avro.file.DataFileStream.getMetaString dfs.getMetaString(AvroDataFile.this.SftNameKey)
59 142 2232 - 2242 Select org.locationtech.geomesa.features.avro.io.AvroDataFile.SftSpecKey AvroDataFile.this.SftSpecKey
59 143 2214 - 2243 Apply org.apache.avro.file.DataFileStream.getMetaString dfs.getMetaString(AvroDataFile.this.SftSpecKey)
60 144 2248 - 2297 Apply org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes.createType org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes.createType(sftName, sftString)