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 ;
33- import io .confluent .common .utils .IntegrationTest ;
34- import io .confluent .kafka .schemaregistry .CompatibilityLevel ;
35- 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 ;
5330import org .apache .avro .file .DataFileReader ;
5431import org .apache .avro .generic .GenericDatumReader ;
5532import org .apache .avro .generic .GenericRecord ;
7956import org .slf4j .Logger ;
8057import org .slf4j .LoggerFactory ;
8158
59+ import java .io .BufferedReader ;
60+ import java .io .File ;
61+ import java .io .FileReader ;
62+ import java .io .IOException ;
63+ import java .net .ServerSocket ;
64+ import java .util .ArrayList ;
65+ import java .util .Arrays ;
66+ import java .util .HashMap ;
67+ import java .util .List ;
68+ import java .util .Map ;
69+ import java .util .Objects ;
70+ import java .util .Properties ;
71+ import java .util .concurrent .TimeUnit ;
72+ import java .util .function .Function ;
73+ import java .util .stream .Collectors ;
74+
75+ import io .confluent .common .utils .IntegrationTest ;
76+ import io .confluent .connect .s3 .util .S3Utils ;
77+ import io .confluent .kafka .schemaregistry .CompatibilityLevel ;
78+ import io .confluent .kafka .schemaregistry .RestApp ;
79+
80+ import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_ACCESS_KEY_ID_CONFIG ;
81+ import static io .confluent .connect .s3 .S3SinkConnectorConfig .AWS_SECRET_ACCESS_KEY_CONFIG ;
82+ import static io .confluent .kafka .schemaregistry .ClusterTestHarness .KAFKASTORE_TOPIC ;
8283import static org .assertj .core .api .Assertions .assertThat ;
8384
8485@ Category (IntegrationTest .class )
@@ -332,15 +333,15 @@ protected Schema getSampleStructSchema() {
332333 .field ("myFloat32" , Schema .FLOAT32_SCHEMA )
333334 .field ("myFloat64" , Schema .FLOAT64_SCHEMA )
334335 .field ("myString" , Schema .STRING_SCHEMA )
336+ .field ("withDefault" , SchemaBuilder .bool ().optional ().defaultValue (true ).build ())
335337 .build ();
336338 }
337339
338340 protected Struct getSampleStructVal (Schema structSchema ) {
339- Date sampleDate = new Date (1111111 );
340- sampleDate .setTime (0 );
341341 return new Struct (structSchema )
342342 .put ("ID" , (long ) 1 )
343343 .put ("myBool" , true )
344+ .put ("withDefault" , null )
344345 .put ("myInt32" , 32 )
345346 .put ("myFloat32" , 3.2f )
346347 .put ("myFloat64" , 64.64 )
@@ -409,12 +410,15 @@ protected static void clearBucket(String bucketName) {
409410 * @param bucketName the name of the s3 test bucket
410411 * @param expectedRowsPerFile the number of rows a file should have
411412 * @param expectedRow the expected row data in each file
413+ * @param useDefaultValues
414+ *
412415 * @return whether every row of the files read equals the expected row
413416 */
414417 protected boolean fileContentsAsExpected (
415418 String bucketName ,
416419 int expectedRowsPerFile ,
417- Struct expectedRow
420+ Struct expectedRow ,
421+ boolean useDefaultValues
418422 ) {
419423 log .info ("expectedRow: {}" , expectedRow );
420424 for (String fileName :
@@ -427,7 +431,7 @@ protected boolean fileContentsAsExpected(
427431 String fileExtension = getExtensionFromKey (fileName );
428432 List <JsonNode > downloadedFileContents = contentGetters .get (fileExtension )
429433 .apply (destinationPath );
430- if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow )) {
434+ if (!fileContentsMatchExpected (downloadedFileContents , expectedRowsPerFile , expectedRow , useDefaultValues )) {
431435 return false ;
432436 }
433437 downloadedFile .delete ();
@@ -481,20 +485,23 @@ protected boolean keyfileContentsAsExpected(
481485 * @param fileContents the file contents as a list of JsonNodes
482486 * @param expectedRowsPerFile the number of rows expected in the file
483487 * @param expectedRow the expected values of each row
488+ * @param useDefaultValues use default values from struct
489+ *
484490 * @return whether the file contents match the expected row
485491 */
486492 protected boolean fileContentsMatchExpected (
487493 List <JsonNode > fileContents ,
488494 int expectedRowsPerFile ,
489- Struct expectedRow
495+ Struct expectedRow ,
496+ boolean useDefaultValues
490497 ) {
491498 if (fileContents .size () != expectedRowsPerFile ) {
492499 log .error ("Number of rows in file do not match the expected count, actual: {}, expected: {}" ,
493500 fileContents .size (), expectedRowsPerFile );
494501 return false ;
495502 }
496503 for (JsonNode row : fileContents ) {
497- if (!fileRowMatchesExpectedRow (row , expectedRow )) {
504+ if (!fileRowMatchesExpectedRow (row , expectedRow , useDefaultValues )) {
498505 return false ;
499506 }
500507 }
@@ -512,18 +519,34 @@ private List<String> getS3KeyFileList(List<S3ObjectSummary> summaries) {
512519 /**
513520 * Compare the row in the file and its values to the expected row's values.
514521 *
515- * @param fileRow the row read from the file as a JsonNode
516- * @param expectedRow the expected contents of the row
522+ * @param fileRow the row read from the file as a JsonNode
523+ * @param expectedRow the expected contents of the row
524+ * @param useDefaultValues
525+ *
517526 * @return whether the file row matches the expected row
518527 */
519- private boolean fileRowMatchesExpectedRow (JsonNode fileRow , Struct expectedRow ) {
520- log .debug ("Comparing rows: file: {}, expected: {}" , fileRow , expectedRow );
528+ private boolean fileRowMatchesExpectedRow (JsonNode fileRow , Struct expectedRow , boolean useDefaultValues ) {
529+ log .info ("Comparing rows: file: {}, expected: {}" , fileRow , expectedRow );
521530 // compare the field values
522531 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 )) {
532+ String expectedValue = null ;
533+ if (useDefaultValues ) {
534+ expectedValue = expectedRow .get (key ).toString ();
535+ } else {
536+ Object withoutDefault = expectedRow .getWithoutDefault (key .name ());
537+ if (withoutDefault != null ) {
538+ expectedValue = withoutDefault .toString ();
539+ }
540+ }
541+
542+ JsonNode jsonValue = fileRow .get (key .name ());
543+ String rowValue = null ;
544+ if (!(jsonValue instanceof NullNode )) {
545+ rowValue = jsonValue .toString ().replaceAll ("^\" |\" $" , "" );
546+ }
547+
548+ log .info ("Comparing values: {}, {}, {}, {}" , key .name (), expectedValue , rowValue , Objects .equals (rowValue , expectedValue ));
549+ if (!Objects .equals (rowValue , expectedValue )) {
527550 return false ;
528551 }
529552 }
0 commit comments