2424import java .io .IOException ;
2525import java .io .InputStream ;
2626import java .util .Map ;
27+ import org .apache .beam .runners .dataflow .options .DataflowStreamingPipelineOptions ;
2728import org .apache .beam .runners .dataflow .util .CloudObject ;
2829import org .apache .beam .runners .dataflow .util .PropertyNames ;
2930import org .apache .beam .runners .dataflow .worker .util .common .worker .NativeReader ;
3233import org .apache .beam .sdk .coders .Coder ;
3334import org .apache .beam .sdk .io .gcp .pubsub .PubsubMessage ;
3435import org .apache .beam .sdk .options .PipelineOptions ;
36+ import org .apache .beam .sdk .options .ValueProvider ;
3537import org .apache .beam .sdk .transforms .SimpleFunction ;
3638import org .apache .beam .sdk .util .SerializableUtils ;
3739import org .apache .beam .sdk .values .WindowedValue ;
4143import org .checkerframework .checker .nullness .qual .Nullable ;
4244
4345/** A Reader that receives elements from Pubsub, via a Windmill server. */
44- @ SuppressWarnings ({
45- "rawtypes" , // TODO(https://github.com/apache/beam/issues/20447)
46- "nullness" // TODO(https://github.com/apache/beam/issues/20497)
47- })
4846class PubsubReader <T > extends NativeReader <WindowedValue <T >> {
4947 private final Coder <T > coder ;
5048 private final StreamingModeExecutionContext context ;
5149 // Function used to parse Windmill data.
5250 // If non-null, data from Windmill is expected to be a PubsubMessage protobuf.
53- private final SimpleFunction <PubsubMessage , T > parseFn ;
51+ private final @ Nullable SimpleFunction <PubsubMessage , T > parseFn ;
52+ private final ValueProvider <Boolean > skipUndecodableElements ;
5453
5554 PubsubReader (
5655 Coder <WindowedValue <T >> coder ,
5756 StreamingModeExecutionContext context ,
58- SimpleFunction <PubsubMessage , T > parseFn ) {
59- @ SuppressWarnings ({ "unchecked" , "rawtypes" })
60- WindowedValueCoder <T > windowedCoder = (WindowedValueCoder ) coder ;
57+ @ Nullable SimpleFunction <PubsubMessage , T > parseFn ,
58+ ValueProvider < Boolean > skipUndecodableElements ) {
59+ WindowedValueCoder <T > windowedCoder = (WindowedValueCoder < T > ) coder ;
6160 this .coder = windowedCoder .getValueCoder ();
6261 this .context = context ;
6362 this .parseFn = parseFn ;
63+ this .skipUndecodableElements = skipUndecodableElements ;
6464 }
6565
6666 /** A {@link ReaderFactory.Registrar} for pubsub sources. */
@@ -75,19 +75,19 @@ public Map<String, ReaderFactory> factories() {
7575 }
7676 }
7777
78+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
7879 static class Factory implements ReaderFactory {
7980 @ Override
8081 public NativeReader <?> create (
8182 CloudObject cloudSourceSpec ,
82- Coder <?> coder ,
83+ @ Nullable Coder <?> coder ,
8384 @ Nullable PipelineOptions options ,
8485 @ Nullable DataflowExecutionContext executionContext ,
8586 DataflowOperationContext operationContext )
8687 throws Exception {
87- coder = checkArgumentNotNull (coder );
88- @ SuppressWarnings ("unchecked" )
89- Coder <WindowedValue <Object >> typedCoder = (Coder <WindowedValue <Object >>) coder ;
90- SimpleFunction <PubsubMessage , Object > parseFn = null ;
88+ Coder <WindowedValue <Object >> typedCoder =
89+ (Coder <WindowedValue <Object >>) checkArgumentNotNull (coder );
90+ @ Nullable SimpleFunction <PubsubMessage , Object > parseFn = null ;
9191 byte [] attributesFnBytes =
9292 getBytes (cloudSourceSpec , PropertyNames .PUBSUB_SERIALIZED_ATTRIBUTES_FN , null );
9393 // If attributesFnBytes is set, Pubsub data will be in PubsubMessage protobuf format. The
@@ -98,8 +98,20 @@ public NativeReader<?> create(
9898 (SimpleFunction <PubsubMessage , Object >)
9999 SerializableUtils .deserializeFromByteArray (attributesFnBytes , "serialized fn info" );
100100 }
101+ @ Nullable
102+ ValueProvider <Boolean > skipUndecodableElements =
103+ (options != null )
104+ ? options
105+ .as (DataflowStreamingPipelineOptions .class )
106+ .getSkipInputElementsWithDecodingExceptions ()
107+ : null ;
101108 return new PubsubReader <>(
102- typedCoder , (StreamingModeExecutionContext ) executionContext , parseFn );
109+ typedCoder ,
110+ (StreamingModeExecutionContext ) checkArgumentNotNull (executionContext ),
111+ parseFn ,
112+ skipUndecodableElements != null
113+ ? skipUndecodableElements
114+ : ValueProvider .StaticValueProvider .of (false ));
103115 }
104116 }
105117
@@ -110,7 +122,7 @@ public NativeReaderIterator<WindowedValue<T>> iterator() throws IOException {
110122
111123 class PubsubReaderIterator extends WindmillReaderIteratorBase <T > {
112124 protected PubsubReaderIterator (Windmill .WorkItem work ) {
113- super (work );
125+ super (work , skipUndecodableElements );
114126 }
115127
116128 @ Override
0 commit comments