1515
1616package io .confluent .connect .s3 .integration ;
1717
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-
2218import com .amazonaws .auth .AWSStaticCredentialsProvider ;
2319import com .amazonaws .auth .BasicAWSCredentials ;
2420import com .amazonaws .services .s3 .AmazonS3 ;
2925import com .amazonaws .services .s3 .model .S3ObjectSummary ;
3026import com .fasterxml .jackson .databind .JsonNode ;
3127import com .fasterxml .jackson .databind .ObjectMapper ;
28+ import com .fasterxml .jackson .databind .node .NullNode ;
3229import com .google .common .collect .ImmutableMap ;
3330import io .confluent .common .utils .IntegrationTest ;
31+ import io .confluent .connect .s3 .util .S3Utils ;
3432import io .confluent .kafka .schemaregistry .CompatibilityLevel ;
3533import 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 ;
5334import org .apache .avro .file .DataFileReader ;
5435import org .apache .avro .generic .GenericDatumReader ;
5536import org .apache .avro .generic .GenericRecord ;
7960import org .slf4j .Logger ;
8061import org .slf4j .LoggerFactory ;
8162
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 ;
8282import static org .assertj .core .api .Assertions .assertThat ;
8383
8484@ Category (IntegrationTest .class )
@@ -332,15 +332,15 @@ protected Schema getSampleStructSchema() {
332332 .field ("myFloat32" , Schema .FLOAT32_SCHEMA )
333333 .field ("myFloat64" , Schema .FLOAT64_SCHEMA )
334334 .field ("myString" , Schema .STRING_SCHEMA )
335+ .field ("withDefault" , SchemaBuilder .bool ().optional ().defaultValue (true ).build ())
335336 .build ();
336337 }
337338
338339 protected Struct getSampleStructVal (Schema structSchema ) {
339- Date sampleDate = new Date (1111111 );
340- sampleDate .setTime (0 );
341340 return new Struct (structSchema )
342341 .put ("ID" , (long ) 1 )
343342 .put ("myBool" , true )
343+ .put ("withDefault" , null )
344344 .put ("myInt32" , 32 )
345345 .put ("myFloat32" , 3.2f )
346346 .put ("myFloat64" , 64.64 )
@@ -409,12 +409,15 @@ protected static void clearBucket(String bucketName) {
409409 * @param bucketName the name of the s3 test bucket
410410 * @param expectedRowsPerFile the number of rows a file should have
411411 * @param expectedRow the expected row data in each file
412+ * @param useDefaultValues
413+ *
412414 * @return whether every row of the files read equals the expected row
413415 */
414416 protected boolean fileContentsAsExpected (
415417 String bucketName ,
416418 int expectedRowsPerFile ,
417- Struct expectedRow
419+ Struct expectedRow ,
420+ boolean useDefaultValues
418421 ) {
419422 log .info ("expectedRow: {}" , expectedRow );
420423 for (String fileName :
@@ -427,7 +430,7 @@ protected boolean fileContentsAsExpected(
427430 String fileExtension = getExtensionFromKey (fileName );
428431 List <JsonNode > downloadedFileContents = contentGetters .get (fileExtension )
429432 .apply (destinationPath );
430- if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow )) {
433+ if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow , useDefaultValues )) {
431434 return false ;
432435 }
433436 downloadedFile .delete ();
@@ -481,20 +484,23 @@ protected boolean keyfileContentsAsExpected(
481484 * @param fileContents the file contents as a list of JsonNodes
482485 * @param expectedRowsPerFile the number of rows expected in the file
483486 * @param expectedRow the expected values of each row
487+ * @param useDefaultValues use default values from struct
488+ *
484489 * @return whether the file contents match the expected row
485490 */
486491 protected boolean fileContentsMatchExpected (
487492 List <JsonNode > fileContents ,
488493 int expectedRowsPerFile ,
489- Struct expectedRow
494+ Struct expectedRow ,
495+ boolean useDefaultValues
490496 ) {
491497 if (fileContents .size () != expectedRowsPerFile ) {
492498 log .error ("Number of rows in file do not match the expected count, actual: {}, expected: {}" ,
493499 fileContents .size (), expectedRowsPerFile );
494500 return false ;
495501 }
496502 for (JsonNode row : fileContents ) {
497- if (!fileRowMatchesExpectedRow (row , expectedRow )) {
503+ if (!fileRowMatchesExpectedRow (row , expectedRow , useDefaultValues )) {
498504 return false ;
499505 }
500506 }
@@ -512,18 +518,34 @@ private List<String> getS3KeyFileList(List<S3ObjectSummary> summaries) {
512518 /**
513519 * Compare the row in the file and its values to the expected row's values.
514520 *
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+ *
517525 * @return whether the file row matches the expected row
518526 */
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 );
521529 // compare the field values
522530 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 )) {
527549 return false ;
528550 }
529551 }
0 commit comments