1818
1919import java .time .Instant ;
2020import java .time .ZoneId ;
21+ import java .time .ZoneOffset ;
2122import java .time .ZonedDateTime ;
23+ import java .util .Locale ;
24+ import java .util .Objects ;
2225
2326import org .apache .kafka .connect .header .Header ;
2427import org .apache .kafka .connect .sink .SinkRecord ;
@@ -39,58 +42,67 @@ enum Type {
3942 CUSTOM
4043
4144 }
45+ class Builder {
46+ private ZoneId zoneId = ZoneOffset .UTC ;
47+ private Type type ;
48+ private String additionalParameters ;
4249
43- static TimestampSource forConfiguration (final String configuration , final ZoneId zoneId ) {
44- final String [] parts = configuration .split (":" , 2 );
45- final String typeName = parts [0 ];
46- final String context = parts .length > 1 ? parts [1 ] : null ;
47- for (final Type t : Type .values ()) {
48- if (t .name ().equalsIgnoreCase (typeName )) {
49- return create (t , context , zoneId );
50- }
50+ public Builder zoneId (final ZoneId zoneId ) {
51+ Objects .requireNonNull (zoneId , "zoneId cannot be null" );
52+ this .zoneId = zoneId ;
53+ return this ;
5154 }
52- throw new IllegalArgumentException (String .format ("Unknown timestamp source: %s" , configuration ));
53- }
5455
55- private static TimestampSource create (Type t , String context , ZoneId zoneId ) {
56- switch (t ) {
57- case WALLCLOCK :
58- if (context != null ) {
59- throw new IllegalArgumentException ("Wallclock timestamp source does not support context" );
60- }
61- return new WallclockTimestampSource (zoneId );
62- case EVENT :
63- if (context != null ) {
64- throw new IllegalArgumentException ("Event timestamp source does not support context" );
65- }
66- return new EventTimestampSource (zoneId );
67- case DATA :
68- if (context == null ) {
69- throw new IllegalArgumentException ("Data timestamp source requires context" );
70- }
71- return new DataTimestampSource (context , zoneId );
72- case HEADER :
73- if (context == null ) {
74- throw new IllegalArgumentException ("Header timestamp source requires context" );
75- }
76- return new HeaderTimestampSource (context , zoneId );
77- case CUSTOM :
78- if (context == null ) {
79- throw new IllegalArgumentException ("Header timestamp source requires context" );
80- }
81- final String [] parts = context .split (":" , 2 );
82- final String className = parts [0 ];
83- final String params = parts .length > 1 ? parts [1 ] : null ;
84- try {
85- final Class <?> clazz = Class .forName (className );
86- return (TimestampSource ) clazz .getConstructor (String .class , ZoneId .class ).newInstance (params , zoneId );
87- } catch (final Exception e ) {
88- throw new IllegalArgumentException ("Failed to create custom timestamp source" , e );
89- }
90- default :
91- throw new IllegalArgumentException (
92- String .format ("Unsupported timestamp extractor type: %s" , t ));
56+ public Builder configuration (final String configuration ) {
57+ final String [] parts = configuration .split (":" , 2 );
58+ final String typeName = parts [0 ];
59+ this .type = Type .valueOf (typeName .toUpperCase (Locale .ENGLISH ));
60+
61+ this .additionalParameters = parts .length > 1 ? parts [1 ] : null ;
62+ return this ;
9363 }
64+
65+ public TimestampSource build () {
66+ switch (type ) {
67+ case WALLCLOCK :
68+ if (additionalParameters != null ) {
69+ throw new IllegalArgumentException ("Wallclock timestamp source does not support additionalParameters" );
70+ }
71+ return new WallclockTimestampSource (zoneId );
72+ case EVENT :
73+ if (additionalParameters != null ) {
74+ throw new IllegalArgumentException ("Event timestamp source does not support additionalParameters" );
75+ }
76+ return new EventTimestampSource (zoneId );
77+ case DATA :
78+ if (additionalParameters == null ) {
79+ throw new IllegalArgumentException ("Data timestamp source requires additionalParameters" );
80+ }
81+ return new DataTimestampSource (additionalParameters , zoneId );
82+ case HEADER :
83+ if (additionalParameters == null ) {
84+ throw new IllegalArgumentException ("Header timestamp source requires additionalParameters" );
85+ }
86+ return new HeaderTimestampSource (additionalParameters , zoneId );
87+ case CUSTOM :
88+ if (additionalParameters == null ) {
89+ throw new IllegalArgumentException ("Header timestamp source requires additionalParameters" );
90+ }
91+ final String [] parts = additionalParameters .split (":" , 2 );
92+ final String className = parts [0 ];
93+ final String params = parts .length > 1 ? parts [1 ] : null ;
94+ try {
95+ final Class <?> clazz = Class .forName (className );
96+ return (TimestampSource ) clazz .getConstructor (String .class , ZoneId .class ).newInstance (params , zoneId );
97+ } catch (final Exception e ) {
98+ throw new IllegalArgumentException ("Failed to create custom timestamp source" , e );
99+ }
100+ default :
101+ throw new IllegalArgumentException (
102+ String .format ("Unsupported timestamp extractor type: %s" , type ));
103+ }
104+ }
105+
94106 }
95107
96108 abstract class AbstractTimestampSource implements TimestampSource {
@@ -148,16 +160,16 @@ public ZonedDateTime time(final SinkRecord record) {
148160 }
149161
150162 final class DataTimestampSource extends AbstractTimestampSource {
151- private final Path path ;
163+ private final PathAccess path ;
152164
153165 DataTimestampSource (final String pathDefinition , final ZoneId zoneId ) {
154166 super (zoneId , Type .DATA );
155- this .path = Path .parse (pathDefinition );
167+ this .path = PathAccess .parse (pathDefinition );
156168 }
157169
158170 @ Override
159171 public ZonedDateTime time (final SinkRecord record ) {
160- Object value = path .extractDataFrom (record );
172+ final Object value = path .extractDataFrom (record );
161173 return rawTime (value );
162174 }
163175
@@ -173,7 +185,7 @@ final class HeaderTimestampSource extends AbstractTimestampSource {
173185
174186 @ Override
175187 public ZonedDateTime time (final SinkRecord record ) {
176- Header header = record .headers ().lastWithName (headerName );
188+ final Header header = record .headers ().lastWithName (headerName );
177189 return rawTime (header == null ? null : header .value ());
178190 }
179191 }
0 commit comments