15
15
16
16
package io .confluent .connect .s3 .integration ;
17
17
18
- import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_ACCESS_KEY_ID_CONFIG ;
19
- import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_SECRET_ACCESS_KEY_CONFIG ;
20
- import static io .confluent .kafka .schemaregistry .ClusterTestHarness .KAFKASTORE_TOPIC ;
21
-
22
18
import com .amazonaws .auth .AWSStaticCredentialsProvider ;
23
19
import com .amazonaws .auth .BasicAWSCredentials ;
24
20
import com .amazonaws .services .s3 .AmazonS3 ;
29
25
import com .amazonaws .services .s3 .model .S3ObjectSummary ;
30
26
import com .fasterxml .jackson .databind .JsonNode ;
31
27
import com .fasterxml .jackson .databind .ObjectMapper ;
28
+ import com .fasterxml .jackson .databind .node .NullNode ;
32
29
import com .google .common .collect .ImmutableMap ;
33
30
import io .confluent .common .utils .IntegrationTest ;
31
+ import io .confluent .connect .s3 .util .S3Utils ;
34
32
import io .confluent .kafka .schemaregistry .CompatibilityLevel ;
35
33
import io .confluent .kafka .schemaregistry .RestApp ;
36
- import java .io .BufferedReader ;
37
- import java .io .File ;
38
- import java .io .FileReader ;
39
- import java .io .IOException ;
40
- import java .net .ServerSocket ;
41
- import java .util .ArrayList ;
42
- import java .util .Arrays ;
43
- import java .util .Date ;
44
- import java .util .HashMap ;
45
- import java .util .List ;
46
- import java .util .Map ;
47
- import java .util .Properties ;
48
- import java .util .concurrent .TimeUnit ;
49
-
50
- import io .confluent .connect .s3 .util .S3Utils ;
51
- import java .util .function .Function ;
52
- import java .util .stream .Collectors ;
53
34
import org .apache .avro .file .DataFileReader ;
54
35
import org .apache .avro .generic .GenericDatumReader ;
55
36
import org .apache .avro .generic .GenericRecord ;
79
60
import org .slf4j .Logger ;
80
61
import org .slf4j .LoggerFactory ;
81
62
63
+ import java .io .BufferedReader ;
64
+ import java .io .File ;
65
+ import java .io .FileReader ;
66
+ import java .io .IOException ;
67
+ import java .net .ServerSocket ;
68
+ import java .util .ArrayList ;
69
+ import java .util .Arrays ;
70
+ import java .util .HashMap ;
71
+ import java .util .List ;
72
+ import java .util .Map ;
73
+ import java .util .Objects ;
74
+ import java .util .Properties ;
75
+ import java .util .concurrent .TimeUnit ;
76
+ import java .util .function .Function ;
77
+ import java .util .stream .Collectors ;
78
+
79
+ import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_ACCESS_KEY_ID_CONFIG ;
80
+ import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_SECRET_ACCESS_KEY_CONFIG ;
81
+ import static io .confluent .kafka .schemaregistry .ClusterTestHarness .KAFKASTORE_TOPIC ;
82
82
import static org .assertj .core .api .Assertions .assertThat ;
83
83
84
84
@ Category (IntegrationTest .class )
@@ -332,15 +332,15 @@ protected Schema getSampleStructSchema() {
332
332
.field ("myFloat32" , Schema .FLOAT32_SCHEMA )
333
333
.field ("myFloat64" , Schema .FLOAT64_SCHEMA )
334
334
.field ("myString" , Schema .STRING_SCHEMA )
335
+ .field ("withDefault" , SchemaBuilder .bool ().optional ().defaultValue (true ).build ())
335
336
.build ();
336
337
}
337
338
338
339
protected Struct getSampleStructVal (Schema structSchema ) {
339
- Date sampleDate = new Date (1111111 );
340
- sampleDate .setTime (0 );
341
340
return new Struct (structSchema )
342
341
.put ("ID" , (long ) 1 )
343
342
.put ("myBool" , true )
343
+ .put ("withDefault" , null )
344
344
.put ("myInt32" , 32 )
345
345
.put ("myFloat32" , 3.2f )
346
346
.put ("myFloat64" , 64.64 )
@@ -409,12 +409,15 @@ protected static void clearBucket(String bucketName) {
409
409
* @param bucketName the name of the s3 test bucket
410
410
* @param expectedRowsPerFile the number of rows a file should have
411
411
* @param expectedRow the expected row data in each file
412
+ * @param useDefaultValues
413
+ *
412
414
* @return whether every row of the files read equals the expected row
413
415
*/
414
416
protected boolean fileContentsAsExpected (
415
417
String bucketName ,
416
418
int expectedRowsPerFile ,
417
- Struct expectedRow
419
+ Struct expectedRow ,
420
+ boolean useDefaultValues
418
421
) {
419
422
log .info ("expectedRow: {}" , expectedRow );
420
423
for (String fileName :
@@ -427,7 +430,7 @@ protected boolean fileContentsAsExpected(
427
430
String fileExtension = getExtensionFromKey (fileName );
428
431
List <JsonNode > downloadedFileContents = contentGetters .get (fileExtension )
429
432
.apply (destinationPath );
430
- if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow )) {
433
+ if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow , useDefaultValues )) {
431
434
return false ;
432
435
}
433
436
downloadedFile .delete ();
@@ -481,20 +484,23 @@ protected boolean keyfileContentsAsExpected(
481
484
* @param fileContents the file contents as a list of JsonNodes
482
485
* @param expectedRowsPerFile the number of rows expected in the file
483
486
* @param expectedRow the expected values of each row
487
+ * @param useDefaultValues use default values from struct
488
+ *
484
489
* @return whether the file contents match the expected row
485
490
*/
486
491
protected boolean fileContentsMatchExpected (
487
492
List <JsonNode > fileContents ,
488
493
int expectedRowsPerFile ,
489
- Struct expectedRow
494
+ Struct expectedRow ,
495
+ boolean useDefaultValues
490
496
) {
491
497
if (fileContents .size () != expectedRowsPerFile ) {
492
498
log .error ("Number of rows in file do not match the expected count, actual: {}, expected: {}" ,
493
499
fileContents .size (), expectedRowsPerFile );
494
500
return false ;
495
501
}
496
502
for (JsonNode row : fileContents ) {
497
- if (!fileRowMatchesExpectedRow (row , expectedRow )) {
503
+ if (!fileRowMatchesExpectedRow (row , expectedRow , useDefaultValues )) {
498
504
return false ;
499
505
}
500
506
}
@@ -512,18 +518,34 @@ private List<String> getS3KeyFileList(List<S3ObjectSummary> summaries) {
512
518
/**
513
519
* Compare the row in the file and its values to the expected row's values.
514
520
*
515
- * @param fileRow the row read from the file as a JsonNode
516
- * @param expectedRow the expected contents of the row
521
+ * @param fileRow the row read from the file as a JsonNode
522
+ * @param expectedRow the expected contents of the row
523
+ * @param useDefaultValues
524
+ *
517
525
* @return whether the file row matches the expected row
518
526
*/
519
- private boolean fileRowMatchesExpectedRow (JsonNode fileRow , Struct expectedRow ) {
520
- log .debug ("Comparing rows: file: {}, expected: {}" , fileRow , expectedRow );
527
+ private boolean fileRowMatchesExpectedRow (JsonNode fileRow , Struct expectedRow , boolean useDefaultValues ) {
528
+ log .info ("Comparing rows: file: {}, expected: {}" , fileRow , expectedRow );
521
529
// compare the field values
522
530
for (Field key : expectedRow .schema ().fields ()) {
523
- String expectedValue = expectedRow .get (key ).toString ();
524
- String rowValue = fileRow .get (key .name ()).toString ().replaceAll ("^\" |\" $" , "" );
525
- log .debug ("Comparing values: {}, {}" , expectedValue , rowValue );
526
- if (!rowValue .equals (expectedValue )) {
531
+ String expectedValue = null ;
532
+ if (useDefaultValues ) {
533
+ expectedValue = expectedRow .get (key ).toString ();
534
+ } else {
535
+ Object withoutDefault = expectedRow .getWithoutDefault (key .name ());
536
+ if (withoutDefault != null ) {
537
+ expectedValue = withoutDefault .toString ();
538
+ }
539
+ }
540
+
541
+ JsonNode jsonValue = fileRow .get (key .name ());
542
+ String rowValue = null ;
543
+ if (!(jsonValue instanceof NullNode )) {
544
+ rowValue = jsonValue .toString ().replaceAll ("^\" |\" $" , "" );
545
+ }
546
+
547
+ log .info ("Comparing values: {}, {}, {}, {}" , key .name (), expectedValue , rowValue , Objects .equals (rowValue , expectedValue ));
548
+ if (!Objects .equals (rowValue , expectedValue )) {
527
549
return false ;
528
550
}
529
551
}
0 commit comments