1616 */
1717package feast .ingestion
1818
19- import java .sql
20-
21- import com .google .protobuf .Descriptors .{Descriptor , EnumValueDescriptor , FieldDescriptor }
22- import com .google .protobuf .{AbstractMessage , ByteString , GeneratedMessageV3 , Parser , Timestamp }
19+ import feast .ingestion .registry .proto .ProtoRegistryFactory
2320import org .apache .spark .sql .{DataFrame , Row , SaveMode , SparkSession }
2421import org .apache .spark .sql .functions .udf
25- import org .apache .spark .sql .types ._
26- import com .google .protobuf .Descriptors .FieldDescriptor .JavaType ._
27- import feast .ingestion .BatchPipeline .inputProjection
2822import feast .ingestion .utils .ProtoReflection
2923import feast .ingestion .validation .RowValidator
3024import org .apache .spark .sql .streaming .StreamingQuery
3125
32- import scala .collection .convert .ImplicitConversions ._
33- import collection .JavaConverters ._
34-
3526object StreamingPipeline extends BasePipeline with Serializable {
3627 override def createPipeline (
3728 sparkSession : SparkSession ,
@@ -42,15 +33,10 @@ object StreamingPipeline extends BasePipeline with Serializable {
4233 val featureTable = config.featureTable
4334 val projection =
4435 inputProjection(config.source, featureTable.features, featureTable.entities)
45- val validator = new RowValidator (featureTable)
36+ val validator = new RowValidator (featureTable, config.source.timestampColumn )
4637
47- val defaultInstance = defaultInstanceFromProtoClass(
48- config.source.asInstanceOf [StreamingSource ].classpath
49- )
50- val protoParser = udf(
51- ProtoReflection .createMessageParser(defaultInstance),
52- inferSchemaFromProto(defaultInstance)
53- )
38+ val messageParser =
39+ protoParser(sparkSession, config.source.asInstanceOf [StreamingSource ].classpath)
5440
5541 val input = config.source match {
5642 case source : KafkaSource =>
@@ -62,7 +48,7 @@ object StreamingPipeline extends BasePipeline with Serializable {
6248 }
6349
6450 val projected = input
65- .withColumn(" features" , protoParser ($" value" ))
51+ .withColumn(" features" , messageParser ($" value" ))
6652 .select(" features.*" )
6753 .select(projection : _* )
6854
@@ -105,17 +91,11 @@ object StreamingPipeline extends BasePipeline with Serializable {
10591 Some (query)
10692 }
10793
108- private def defaultInstanceFromProtoClass (className : String ): GeneratedMessageV3 =
109- Class
110- .forName(className, true , getClass.getClassLoader)
111- .asInstanceOf [Class [GeneratedMessageV3 ]]
112- .getMethod(" getDefaultInstance" )
113- .invoke(null )
114- .asInstanceOf [GeneratedMessageV3 ]
94+ private def protoParser (sparkSession : SparkSession , className : String ) = {
95+ val protoRegistry = ProtoRegistryFactory .resolveProtoRegistry(sparkSession)
11596
116- private def inferSchemaFromProto (defaultInstance : GeneratedMessageV3 ) =
117- StructType (
118- defaultInstance.getDescriptorForType.getFields.flatMap(ProtoReflection .structFieldFor)
119- )
97+ val parser : Array [Byte ] => Row = ProtoReflection .createMessageParser(protoRegistry, className)
12098
99+ udf(parser, ProtoReflection .inferSchema(protoRegistry.getProtoDescriptor(className)))
100+ }
121101}
0 commit comments