This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new f92f6f1def NIFI-13578 Add Schema Branch Name and Schema Version in
ValidateRecord (#9108)
f92f6f1def is described below
commit f92f6f1def97d0252dd16eef56b6147efe86ca52
Author: Juldrixx <[email protected]>
AuthorDate: Sat Aug 31 17:54:26 2024 +0200
NIFI-13578 Add Schema Branch Name and Schema Version in ValidateRecord
(#9108)
Signed-off-by: David Handermann <[email protected]>
---
.../src/main/java/org/apache/nifi/util/Triple.java | 21 +
.../serialization/record/MockSchemaRegistry.java | 37 +-
.../nifi/processors/standard/ValidateRecord.java | 59 ++-
.../processors/standard/TestValidateRecord.java | 453 ++++++++++++++++-----
4 files changed, 421 insertions(+), 149 deletions(-)
diff --git
a/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/Triple.java
b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/Triple.java
new file mode 100644
index 0000000000..a5a8b807e4
--- /dev/null
+++ b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/Triple.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.util;
+
+public record Triple<A, B, C>(A first, B second, C third) {
+
+}
diff --git
a/nifi-extension-bundles/nifi-extension-utils/nifi-record-utils/nifi-mock-record-utils/src/main/java/org/apache/nifi/serialization/record/MockSchemaRegistry.java
b/nifi-extension-bundles/nifi-extension-utils/nifi-record-utils/nifi-mock-record-utils/src/main/java/org/apache/nifi/serialization/record/MockSchemaRegistry.java
index 972044b973..eac76b8ffa 100644
---
a/nifi-extension-bundles/nifi-extension-utils/nifi-record-utils/nifi-mock-record-utils/src/main/java/org/apache/nifi/serialization/record/MockSchemaRegistry.java
+++
b/nifi-extension-bundles/nifi-extension-utils/nifi-record-utils/nifi-mock-record-utils/src/main/java/org/apache/nifi/serialization/record/MockSchemaRegistry.java
@@ -22,8 +22,8 @@ import org.apache.nifi.schema.access.SchemaField;
import org.apache.nifi.schema.access.SchemaNotFoundException;
import org.apache.nifi.schemaregistry.services.SchemaRegistry;
import org.apache.nifi.util.Tuple;
+import org.apache.nifi.util.Triple;
-import java.io.IOException;
import java.util.EnumSet;
import java.util.Optional;
import java.util.OptionalInt;
@@ -33,40 +33,53 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class MockSchemaRegistry extends AbstractControllerService implements
SchemaRegistry {
- private final ConcurrentMap<String, RecordSchema> schemaNameMap = new
ConcurrentHashMap<>();
+ private final ConcurrentMap<Triple<String, String, Integer>, RecordSchema>
schemaNameMap = new ConcurrentHashMap<>();
private final ConcurrentMap<Tuple<Long, Integer>, RecordSchema>
schemaIdVersionMap = new ConcurrentHashMap<>();
public void addSchema(final String name, final RecordSchema schema) {
- schemaNameMap.put(name, schema);
+ addSchema(name, null, null, schema);
}
- RecordSchema retrieveSchemaByName(final SchemaIdentifier schemaIdentifier)
throws IOException, SchemaNotFoundException {
+ public void addSchema(final String name, final String branch, final
RecordSchema schema) {
+ addSchema(name, branch, null, schema);
+ }
+
+ public void addSchema(final String name, final Integer version, final
RecordSchema schema) {
+ addSchema(name, null, version, schema);
+ }
+
+ public void addSchema(final String name, final String branch, final
Integer version, final RecordSchema schema) {
+ schemaNameMap.put(new Triple<>(name, branch, version), schema);
+ }
+
+ RecordSchema retrieveSchemaByName(final SchemaIdentifier schemaIdentifier)
throws SchemaNotFoundException {
final Optional<String> schemaName = schemaIdentifier.getName();
- if (!schemaName.isPresent()) {
+ if (schemaName.isEmpty()) {
throw new
org.apache.nifi.schema.access.SchemaNotFoundException("Cannot retrieve schema
because Schema Name is not present");
}
- return schemaNameMap.get(schemaName.get());
+ final String schemaBranch = schemaIdentifier.getBranch().orElse(null);
+ final Integer schemaVersion =
schemaIdentifier.getVersion().isPresent() ?
schemaIdentifier.getVersion().getAsInt() : null;
+ return schemaNameMap.get(new Triple<>(schemaName.get(), schemaBranch,
schemaVersion));
}
- private RecordSchema retrieveSchemaByIdAndVersion(final SchemaIdentifier
schemaIdentifier) throws IOException, SchemaNotFoundException {
+ private RecordSchema retrieveSchemaByIdAndVersion(final SchemaIdentifier
schemaIdentifier) throws SchemaNotFoundException {
final OptionalLong schemaId = schemaIdentifier.getIdentifier();
- if (!schemaId.isPresent()) {
+ if (schemaId.isEmpty()) {
throw new
org.apache.nifi.schema.access.SchemaNotFoundException("Cannot retrieve schema
because Schema Id is not present");
}
final OptionalInt version = schemaIdentifier.getVersion();
- if (!version.isPresent()) {
+ if (version.isEmpty()) {
throw new
org.apache.nifi.schema.access.SchemaNotFoundException("Cannot retrieve schema
because Schema Version is not present");
}
final Tuple<Long, Integer> tuple = new Tuple<>(schemaId.getAsLong(),
version.getAsInt());
- final RecordSchema schema = schemaIdVersionMap.get(tuple);
- return schema;
+ return schemaIdVersionMap.get(tuple);
}
@Override
- public RecordSchema retrieveSchema(final SchemaIdentifier
schemaIdentifier) throws IOException, SchemaNotFoundException {
+ public RecordSchema retrieveSchema(final SchemaIdentifier
schemaIdentifier) throws SchemaNotFoundException {
if (schemaIdentifier.getName().isPresent()) {
return retrieveSchemaByName(schemaIdentifier);
} else {
diff --git
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ValidateRecord.java
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ValidateRecord.java
index 26466bac09..290c925fa1 100644
---
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ValidateRecord.java
+++
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ValidateRecord.java
@@ -28,7 +28,6 @@ import org.apache.nifi.annotation.behavior.WritesAttribute;
import org.apache.nifi.annotation.behavior.WritesAttributes;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.avro.AvroSchemaValidator;
import org.apache.nifi.avro.AvroTypeUtil;
import org.apache.nifi.components.AllowableValue;
import org.apache.nifi.components.PropertyDescriptor;
@@ -37,6 +36,7 @@ import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.flowfile.attributes.CoreAttributes;
+import org.apache.nifi.migration.PropertyConfiguration;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
@@ -74,6 +74,14 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_BRANCH_NAME;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_NAME;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_NAME_PROPERTY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_REGISTRY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_TEXT;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_TEXT_PROPERTY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_VERSION;
+
@SideEffectFree
@SupportsBatching
@InputRequirement(Requirement.INPUT_REQUIRED)
@@ -89,10 +97,6 @@ import java.util.Set;
})
public class ValidateRecord extends AbstractProcessor {
- static final AllowableValue SCHEMA_NAME_PROPERTY = new
AllowableValue("schema-name-property", "Use Schema Name Property",
- "The schema to validate the data against is determined by looking at
the 'Schema Name' Property and looking up the schema in the configured Schema
Registry");
- static final AllowableValue SCHEMA_TEXT_PROPERTY = new
AllowableValue("schema-text-property", "Use Schema Text Property",
- "The schema to validate the data against is determined by looking at
the 'Schema Text' Property and parsing the schema as an Avro schema");
static final AllowableValue READER_SCHEMA = new
AllowableValue("reader-schema", "Use Reader's Schema",
"The schema to validate the data against is determined by asking the
configured Record Reader for its schema");
@@ -131,31 +135,6 @@ public class ValidateRecord extends AbstractProcessor {
.defaultValue(READER_SCHEMA.getValue())
.required(true)
.build();
- public static final PropertyDescriptor SCHEMA_REGISTRY = new
PropertyDescriptor.Builder()
- .name("schema-registry")
- .displayName("Schema Registry")
- .description("Specifies the Controller Service to use for the Schema
Registry. This is necessary only if the Schema Access Strategy is set to \"Use
'Schema Name' Property\".")
- .identifiesControllerService(SchemaRegistry.class)
- .required(false)
- .build();
- static final PropertyDescriptor SCHEMA_NAME = new
PropertyDescriptor.Builder()
- .name("schema-name")
- .displayName("Schema Name")
- .description("Specifies the name of the schema to lookup in the Schema
Registry property")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
-
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .defaultValue("${schema.name}")
- .required(false)
- .build();
- static final PropertyDescriptor SCHEMA_TEXT = new
PropertyDescriptor.Builder()
- .name("schema-text")
- .displayName("Schema Text")
- .description("The text of an Avro-formatted Schema")
- .addValidator(new AvroSchemaValidator())
-
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .defaultValue("${avro.schema}")
- .required(false)
- .build();
static final PropertyDescriptor ALLOW_EXTRA_FIELDS = new
PropertyDescriptor.Builder()
.name("allow-extra-fields")
.displayName("Allow Extra Fields")
@@ -219,6 +198,8 @@ public class ValidateRecord extends AbstractProcessor {
SCHEMA_ACCESS_STRATEGY,
SCHEMA_REGISTRY,
SCHEMA_NAME,
+ SCHEMA_BRANCH_NAME,
+ SCHEMA_VERSION,
SCHEMA_TEXT,
ALLOW_EXTRA_FIELDS,
STRICT_TYPE_CHECKING,
@@ -256,6 +237,17 @@ public class ValidateRecord extends AbstractProcessor {
return RELATIONSHIPS;
}
+ @Override
+ public void migrateProperties(final PropertyConfiguration config) {
+ if (config.isPropertySet(SCHEMA_ACCESS_STRATEGY)) {
+ config.getPropertyValue(SCHEMA_ACCESS_STRATEGY).ifPresent(value ->
{
+ if (value.equals("schema-name-property")) {
+ config.setProperty(SCHEMA_ACCESS_STRATEGY,
SCHEMA_NAME_PROPERTY.getValue());
+ }
+ });
+ }
+ }
+
@Override
protected Collection<ValidationResult> customValidate(final
ValidationContext validationContext) {
final String schemaAccessStrategy =
validationContext.getProperty(SCHEMA_ACCESS_STRATEGY).getValue();
@@ -482,8 +474,7 @@ public class ValidateRecord extends AbstractProcessor {
final Integer maxValidationDetailsLength =
context.getProperty(MAX_VALIDATION_DETAILS_LENGTH).evaluateAttributeExpressions(flowFile).asInteger();
- final Map<String, String> attributes = new HashMap<>();
- attributes.putAll(writeResult.getAttributes());
+ final Map<String, String> attributes = new
HashMap<>(writeResult.getAttributes());
attributes.put("record.count",
String.valueOf(writeResult.getRecordCount()));
attributes.put(CoreAttributes.MIME_TYPE.key(), writer.getMimeType());
@@ -536,7 +527,9 @@ public class ValidateRecord extends AbstractProcessor {
} else if
(schemaAccessStrategy.equals(SCHEMA_NAME_PROPERTY.getValue())) {
final SchemaRegistry schemaRegistry =
context.getProperty(SCHEMA_REGISTRY).asControllerService(SchemaRegistry.class);
final String schemaName =
context.getProperty(SCHEMA_NAME).evaluateAttributeExpressions(flowFile).getValue();
- final SchemaIdentifier schemaIdentifier =
SchemaIdentifier.builder().name(schemaName).build();
+ final String schemaBranchName =
context.getProperty(SCHEMA_BRANCH_NAME).evaluateAttributeExpressions(flowFile).getValue();
+ final Integer schemaVersion =
context.getProperty(SCHEMA_VERSION).evaluateAttributeExpressions(flowFile).asInteger();
+ final SchemaIdentifier schemaIdentifier =
SchemaIdentifier.builder().name(schemaName).branch(schemaBranchName).version(schemaVersion).build();
return schemaRegistry.retrieveSchema(schemaIdentifier);
} else if
(schemaAccessStrategy.equals(SCHEMA_TEXT_PROPERTY.getValue())) {
final String schemaText =
context.getProperty(SCHEMA_TEXT).evaluateAttributeExpressions(flowFile).getValue();
diff --git
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestValidateRecord.java
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestValidateRecord.java
index 528b1c162c..2be36a6bba 100644
---
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestValidateRecord.java
+++
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestValidateRecord.java
@@ -17,23 +17,25 @@
package org.apache.nifi.processors.standard;
+import org.apache.avro.Schema;
import org.apache.nifi.avro.AvroReader;
import org.apache.nifi.avro.AvroReaderWithEmbeddedSchema;
import org.apache.nifi.avro.AvroRecordReader;
import org.apache.nifi.avro.AvroRecordSetWriter;
+import org.apache.nifi.avro.AvroTypeUtil;
import org.apache.nifi.csv.CSVReader;
import org.apache.nifi.csv.CSVRecordSetWriter;
import org.apache.nifi.csv.CSVUtils;
import org.apache.nifi.json.JsonRecordSetWriter;
import org.apache.nifi.json.JsonTreeReader;
import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.schema.access.SchemaAccessUtils;
import org.apache.nifi.schema.access.SchemaNotFoundException;
import org.apache.nifi.schema.inference.SchemaInferenceUtil;
import org.apache.nifi.serialization.DateTimeUtils;
import org.apache.nifi.serialization.MalformedRecordException;
import org.apache.nifi.serialization.RecordReader;
import org.apache.nifi.serialization.record.MockRecordWriter;
+import org.apache.nifi.serialization.record.MockSchemaRegistry;
import org.apache.nifi.serialization.record.Record;
import org.apache.nifi.serialization.record.RecordField;
import org.apache.nifi.serialization.record.RecordFieldType;
@@ -48,13 +50,19 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_BRANCH_NAME;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_REGISTRY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_NAME;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_NAME_PROPERTY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_TEXT;
+import static
org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_TEXT_PROPERTY;
+import static org.apache.nifi.schema.access.SchemaAccessUtils.SCHEMA_VERSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -87,12 +95,12 @@ public class TestValidateRecord {
runner.enqueue(content);
runner.run();
runner.assertAllFlowFilesTransferred(ValidateRecord.REL_VALID, 1);
-
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0).assertContentEquals(content);
+
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst().assertContentEquals(content);
}
@Test
- public void testWriteFailureRoutesToFaliure() throws
InitializationException {
+ public void testWriteFailureRoutesToFailure() throws
InitializationException {
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "true");
@@ -114,13 +122,13 @@ public class TestValidateRecord {
}
@Test
- public void testAppropriateServiceUsedForInvalidRecords() throws
InitializationException, UnsupportedEncodingException, IOException {
- final String schema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc")),
"UTF-8");
+ public void testAppropriateServiceUsedForInvalidRecords() throws
InitializationException, IOException {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
- runner.setProperty(csvReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(csvReader, SchemaAccessUtils.SCHEMA_TEXT, schema);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "false");
runner.setProperty(csvReader, CSVUtils.QUOTE_MODE,
CSVUtils.QUOTE_MINIMAL.getValue());
runner.setProperty(csvReader, CSVUtils.TRAILING_DELIMITER, "false");
@@ -139,9 +147,11 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
- final String content = "1, John Doe\n"
- + "2, Jane Doe\n"
- + "Three, Jack Doe\n";
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
runner.enqueue(content);
runner.run();
@@ -150,24 +160,26 @@ public class TestValidateRecord {
runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
validFlowFile.assertAttributeEquals("record.count", "2");
- validFlowFile.assertContentEquals("valid\n"
- + "1,John Doe\n"
- + "2,Jane Doe\n");
+ validFlowFile.assertContentEquals("""
+ valid
+ 1,John Doe
+ 2,Jane Doe
+ """);
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertAttributeEquals("record.count", "1");
invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
}
@Test
public void testStrictTypeCheck() throws InitializationException,
IOException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc")),
"UTF-8");
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc"));
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
- runner.setProperty(csvReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "csv-header-derived");
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"csv-header-derived");
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.IGNORE_CSV_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.QUOTE_MODE,
CSVUtils.QUOTE_MINIMAL.getValue());
@@ -185,18 +197,20 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "true");
// The validationSchema expects 'id' to be int, but CSVReader reads it
as 'string'
// with strict type check, the type difference is not allowed.
- final String content = "id, firstName, lastName\n"
- + "1, John, Doe\n"
- + "2, Jane, Doe\n"
- + "Three, Jack, Doe\n";
+ final String content = """
+ id, firstName, lastName
+ 1, John, Doe
+ 2, Jane, Doe
+ Three, Jack, Doe
+ """;
runner.enqueue(content);
runner.run();
@@ -205,22 +219,24 @@ public class TestValidateRecord {
runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertAttributeEquals("record.count", "3");
- final String expectedInvalidContents = "invalid\n"
- + "\"1\",\"John\",\"Doe\"\n"
- + "\"2\",\"Jane\",\"Doe\"\n"
- + "\"Three\",\"Jack\",\"Doe\"\n";
+ final String expectedInvalidContents = """
+ invalid
+ "1","John","Doe"
+ "2","Jane","Doe"
+ "Three","Jack","Doe"
+ """;
invalidFlowFile.assertContentEquals(expectedInvalidContents);
}
@Test
public void testNonStrictTypeCheckWithAvroWriter() throws
InitializationException, IOException, MalformedRecordException,
SchemaNotFoundException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc")),
"UTF-8");
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc"));
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
- runner.setProperty(csvReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "csv-header-derived");
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"csv-header-derived");
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.IGNORE_CSV_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.QUOTE_MODE,
CSVUtils.QUOTE_MINIMAL.getValue());
@@ -238,18 +254,20 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "false");
// The validationSchema expects 'id' to be int, but CSVReader reads it
as 'string'
// with non-strict type check, the type difference should be accepted,
and results should be written as 'int'.
- final String content = "id, firstName, lastName\n"
- + "1, John, Doe\n"
- + "2, Jane, Doe\n"
- + "Three, Jack, Doe\n";
+ final String content = """
+ id, firstName, lastName
+ 1, John, Doe
+ 2, Jane, Doe
+ Three, Jack, Doe
+ """;
runner.enqueue(content);
runner.run();
@@ -260,13 +278,13 @@ public class TestValidateRecord {
final AvroReader avroReader = new AvroReader();
runner.addControllerService("avroReader", avroReader);
- runner.setProperty(avroReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(avroReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
runner.enableControllerService(avroReader);
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
final byte[] validFlowFileBytes = validFlowFile.toByteArray();
try (
final ByteArrayInputStream resultContentStream = new
ByteArrayInputStream(validFlowFileBytes);
- final RecordReader recordReader =
avroReader.createRecordReader(validFlowFile.getAttributes(),
resultContentStream, validFlowFileBytes.length, runner.getLogger());
+ final RecordReader recordReader =
avroReader.createRecordReader(validFlowFile.getAttributes(),
resultContentStream, validFlowFileBytes.length, runner.getLogger())
) {
final RecordSchema resultSchema = recordReader.getSchema();
assertEquals(3, resultSchema.getFieldCount());
@@ -289,10 +307,12 @@ public class TestValidateRecord {
assertEquals("Doe", record.getValue("lastName"));
}
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertAttributeEquals("record.count", "1");
- final String expectedInvalidContents = "invalid\n"
- + "\"Three\",\"Jack\",\"Doe\"\n";
+ final String expectedInvalidContents = """
+ invalid
+ "Three","Jack","Doe"
+ """;
invalidFlowFile.assertContentEquals(expectedInvalidContents);
}
@@ -300,7 +320,7 @@ public class TestValidateRecord {
* This test case demonstrates the limitation on JsonRecordSetWriter
type-coercing when strict type check is disabled.
* Since WriteJsonResult.writeRawRecord doesn't use record schema,
* type coercing does not happen with JsonWriter even if strict type check
is disabled.
- *
+ * <p>
* E.g. When an input "1" as string is given, and output field schema is
int:
* <ul>
* <li>Expected result: "id": 1 (without quote)</li>
@@ -309,11 +329,11 @@ public class TestValidateRecord {
*/
@Test
public void testNonStrictTypeCheckWithJsonWriter() throws
InitializationException, IOException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc")),
"UTF-8");
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string-fields.avsc"));
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
- runner.setProperty(csvReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "csv-header-derived");
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"csv-header-derived");
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.IGNORE_CSV_HEADER, "true");
runner.setProperty(csvReader, CSVUtils.QUOTE_MODE,
CSVUtils.QUOTE_MINIMAL.getValue());
@@ -331,18 +351,20 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "false");
// The validationSchema expects 'id' to be int, but CSVReader reads it
as 'string'
// with non-strict type check, the type difference should be accepted,
and results should be written as 'int'.
- final String content = "id, firstName, lastName\n"
- + "1, John, Doe\n"
- + "2, Jane, Doe\n"
- + "Three, Jack, Doe\n";
+ final String content = """
+ id, firstName, lastName
+ 1, John, Doe
+ 2, Jane, Doe
+ Three, Jack, Doe
+ """;
runner.enqueue(content);
runner.run();
@@ -354,7 +376,7 @@ public class TestValidateRecord {
/*
TODO: JsonRecordSetWriter does not coerce value. Should we fix this??
*/
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
validFlowFile.assertAttributeEquals("record.count", "2");
final String expectedValidContents = "[" +
"{\"id\":\"1\",\"firstName\":\"John\",\"lastName\":\"Doe\"}," +
@@ -362,21 +384,23 @@ public class TestValidateRecord {
"]";
validFlowFile.assertContentEquals(expectedValidContents);
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertAttributeEquals("record.count", "1");
- final String expectedInvalidContents = "invalid\n"
- + "\"Three\",\"Jack\",\"Doe\"\n";
+ final String expectedInvalidContents = """
+ invalid
+ "Three","Jack","Doe"
+ """;
invalidFlowFile.assertContentEquals(expectedInvalidContents);
}
@Test
public void testValidateNestedMap() throws InitializationException,
IOException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestValidateRecord/nested-map-schema.avsc")),
StandardCharsets.UTF_8);
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestValidateRecord/nested-map-schema.avsc"));
final JsonTreeReader jsonReader = new JsonTreeReader();
runner.addControllerService("reader", jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "schema-text-property");
- runner.setProperty(jsonReader, SchemaAccessUtils.SCHEMA_TEXT,
validateSchema);
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"schema-text-property");
+ runner.setProperty(jsonReader, SCHEMA_TEXT, validateSchema);
runner.enableControllerService(jsonReader);
final JsonRecordSetWriter validWriter = new JsonRecordSetWriter();
@@ -390,14 +414,15 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
// Both records should be valid if strict type checking is off
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "false");
-
runner.enqueue(Paths.get("src/test/resources/TestValidateRecord/nested-map-input.json"));
+ final Path nestedMapINputpath =
Paths.get("src/test/resources/TestValidateRecord/nested-map-input.json");
+ runner.enqueue(nestedMapINputpath);
runner.run();
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
@@ -407,7 +432,7 @@ public class TestValidateRecord {
// The second record should be invalid if strict type checking is on
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "true");
-
runner.enqueue(Paths.get("src/test/resources/TestValidateRecord/nested-map-input.json"));
+ runner.enqueue(nestedMapINputpath);
runner.run();
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
@@ -417,12 +442,12 @@ public class TestValidateRecord {
@Test
public void testValidateMissingRequiredArray() throws
InitializationException, IOException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestValidateRecord/missing-array.avsc")),
StandardCharsets.UTF_8);
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestValidateRecord/missing-array.avsc"));
final JsonTreeReader jsonReader = new JsonTreeReader();
runner.addControllerService("reader", jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "schema-text-property");
- runner.setProperty(jsonReader, SchemaAccessUtils.SCHEMA_TEXT,
validateSchema);
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"schema-text-property");
+ runner.setProperty(jsonReader, SCHEMA_TEXT, validateSchema);
runner.enableControllerService(jsonReader);
final JsonRecordSetWriter validWriter = new JsonRecordSetWriter();
@@ -436,8 +461,8 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "true");
@@ -454,12 +479,12 @@ public class TestValidateRecord {
@Test
public void testValidateMissingRequiredArrayWithDefault() throws
InitializationException, IOException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestValidateRecord/missing-array-with-default.avsc")),
StandardCharsets.UTF_8);
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestValidateRecord/missing-array-with-default.avsc"));
final JsonTreeReader jsonReader = new JsonTreeReader();
runner.addControllerService("reader", jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "schema-text-property");
- runner.setProperty(jsonReader, SchemaAccessUtils.SCHEMA_TEXT,
validateSchema);
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"schema-text-property");
+ runner.setProperty(jsonReader, SCHEMA_TEXT, validateSchema);
runner.enableControllerService(jsonReader);
final JsonRecordSetWriter validWriter = new JsonRecordSetWriter();
@@ -473,8 +498,8 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "true");
@@ -492,12 +517,12 @@ public class TestValidateRecord {
@Test
public void testValidateJsonTimestamp() throws IOException,
InitializationException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestValidateRecord/timestamp.avsc")),
StandardCharsets.UTF_8);
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestValidateRecord/timestamp.avsc"));
final JsonTreeReader jsonReader = new JsonTreeReader();
runner.addControllerService("reader", jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "schema-text-property");
- runner.setProperty(jsonReader, SchemaAccessUtils.SCHEMA_TEXT,
validateSchema);
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
"schema-text-property");
+ runner.setProperty(jsonReader, SCHEMA_TEXT, validateSchema);
runner.setProperty(jsonReader, DateTimeUtils.TIMESTAMP_FORMAT,
"yyyy/MM/dd HH:mm:ss");
runner.enableControllerService(jsonReader);
@@ -509,17 +534,18 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER, "writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
runner.setProperty(ValidateRecord.STRICT_TYPE_CHECKING, "true");
-
runner.enqueue(Paths.get("src/test/resources/TestValidateRecord/timestamp.json"));
+ final Path timestampPath =
Paths.get("src/test/resources/TestValidateRecord/timestamp.json");
+ runner.enqueue(timestampPath);
runner.run();
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
validFlowFile.assertContentEquals(new
File("src/test/resources/TestValidateRecord/timestamp.json"));
// Test with a timestamp that has an invalid format.
@@ -527,39 +553,38 @@ public class TestValidateRecord {
runner.disableControllerService(jsonReader);
runner.setProperty(jsonReader, DateTimeUtils.TIMESTAMP_FORMAT,
"yyyy-MM-dd HH:mm:ss");
-
runner.enqueue(Paths.get("src/test/resources/TestValidateRecord/timestamp.json"));
+ runner.enqueue(timestampPath);
runner.enableControllerService(jsonReader);
runner.run();
runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertContentEquals(new
File("src/test/resources/TestValidateRecord/timestamp.json"));
// Test with an Inferred Schema.
runner.disableControllerService(jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY,
SchemaInferenceUtil.INFER_SCHEMA.getValue());
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaInferenceUtil.INFER_SCHEMA.getValue());
runner.setProperty(jsonReader, DateTimeUtils.TIMESTAMP_FORMAT,
"yyyy/MM/dd HH:mm:ss");
runner.enableControllerService(jsonReader);
runner.clearTransferState();
-
runner.enqueue(Paths.get("src/test/resources/TestValidateRecord/timestamp.json"));
+ runner.enqueue(timestampPath);
runner.run();
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
- final MockFlowFile validFlowFileInferredSchema =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFileInferredSchema =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
validFlowFileInferredSchema.assertContentEquals(new
File("src/test/resources/TestValidateRecord/timestamp.json"));
}
@Test
public void testValidateMaps() throws IOException,
InitializationException, MalformedRecordException {
- final String validateSchema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestValidateRecord/int-maps-schema.avsc")),
StandardCharsets.UTF_8);
+ final String validateSchema =
Files.readString(Paths.get("src/test/resources/TestValidateRecord/int-maps-schema.avsc"));
final JsonTreeReader jsonReader = new JsonTreeReader();
runner.addControllerService("reader", jsonReader);
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY, "schema-text-property");
- runner.setProperty(jsonReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(jsonReader, SchemaAccessUtils.SCHEMA_TEXT,
validateSchema);
+ runner.setProperty(jsonReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(jsonReader, SCHEMA_TEXT, validateSchema);
runner.enableControllerService(jsonReader);
final AvroRecordSetWriter avroWriter = new AvroRecordSetWriter();
@@ -568,8 +593,8 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.RECORD_READER, "reader");
runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
- runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(ValidateRecord.SCHEMA_TEXT, validateSchema);
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(SCHEMA_TEXT, validateSchema);
runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER, "writer");
runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
@@ -577,7 +602,7 @@ public class TestValidateRecord {
runner.run();
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
byte[] source = validFlowFile.toByteArray();
@@ -594,13 +619,13 @@ public class TestValidateRecord {
}
@Test
- public void testValidationsDetailsAttributeForInvalidRecords() throws
InitializationException, UnsupportedEncodingException, IOException {
- final String schema = new
String(Files.readAllBytes(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc")),
"UTF-8");
+ public void testValidationsDetailsAttributeForInvalidRecords() throws
InitializationException, IOException {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
final CSVReader csvReader = new CSVReader();
runner.addControllerService("reader", csvReader);
- runner.setProperty(csvReader,
SchemaAccessUtils.SCHEMA_ACCESS_STRATEGY,
SchemaAccessUtils.SCHEMA_TEXT_PROPERTY);
- runner.setProperty(csvReader, SchemaAccessUtils.SCHEMA_TEXT, schema);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
runner.setProperty(csvReader, CSVUtils.FIRST_LINE_IS_HEADER, "false");
runner.setProperty(csvReader, CSVUtils.QUOTE_MODE,
CSVUtils.QUOTE_MINIMAL.getValue());
runner.setProperty(csvReader, CSVUtils.TRAILING_DELIMITER, "false");
@@ -621,9 +646,11 @@ public class TestValidateRecord {
runner.setProperty(ValidateRecord.MAX_VALIDATION_DETAILS_LENGTH,
"150");
runner.setProperty(ValidateRecord.VALIDATION_DETAILS_ATTRIBUTE_NAME,
"valDetails");
- final String content = "1, John Doe\n"
- + "2, Jane Doe\n"
- + "Three, Jack Doe\n";
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
runner.enqueue(content);
runner.run();
@@ -631,7 +658,7 @@ public class TestValidateRecord {
runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
- final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).get(0);
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
invalidFlowFile.assertAttributeEquals("record.count", "1");
invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
invalidFlowFile.assertAttributeExists("valDetails");
@@ -641,11 +668,10 @@ public class TestValidateRecord {
@Test
public void testValidationForNullElementArrayAndMap() throws Exception {
- AvroReader avroReader = new AvroReader();
+ final AvroReader avroReader = new AvroReader();
runner.addControllerService("reader", avroReader);
runner.enableControllerService(avroReader);
-
final MockRecordWriter validWriter = new MockRecordWriter("valid",
false);
runner.addControllerService("writer", validWriter);
runner.enableControllerService(validWriter);
@@ -668,9 +694,228 @@ public class TestValidateRecord {
runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
runner.assertTransferCount(ValidateRecord.REL_VALID, 1);
- final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).get(0);
+ final MockFlowFile validFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_VALID).getFirst();
validFlowFile.assertAttributeEquals("record.count", "1");
validFlowFile.assertContentEquals("valid\n[text, null],{key=null}\n");
}
+ @Test
+ public void testSchemaNameAccess() throws Exception {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
+
+ final MockSchemaRegistry registry = new MockSchemaRegistry();
+ registry.addSchema("record", AvroTypeUtil.createSchema(new
Schema.Parser().parse(schema)));
+ runner.addControllerService("registry", registry);
+ runner.enableControllerService(registry);
+
+ final CSVReader csvReader = new CSVReader();
+ runner.addControllerService("reader", csvReader);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvReader);
+
+ final CSVRecordSetWriter csvWriter = new CSVRecordSetWriter();
+ runner.addControllerService("writer", csvWriter);
+ runner.setProperty(csvWriter, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvWriter, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvWriter);
+
+ final MockRecordWriter invalidWriter = new MockRecordWriter("invalid",
true);
+ runner.addControllerService("invalid-writer", invalidWriter);
+ runner.enableControllerService(invalidWriter);
+
+ runner.setProperty(ValidateRecord.RECORD_READER, "reader");
+ runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
+ runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_NAME_PROPERTY);
+ runner.setProperty(SCHEMA_REGISTRY, "registry");
+ runner.setProperty(SCHEMA_NAME, "record");
+ runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
+ runner.setProperty(ValidateRecord.MAX_VALIDATION_DETAILS_LENGTH,
"150");
+ runner.setProperty(ValidateRecord.VALIDATION_DETAILS_ATTRIBUTE_NAME,
"valDetails");
+
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
+ runner.enqueue(content);
+ runner.run();
+
+ runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
+ runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
+
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
+ invalidFlowFile.assertAttributeEquals("record.count", "1");
+ invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
+ invalidFlowFile.assertAttributeExists("valDetails");
+ invalidFlowFile.assertAttributeEquals("valDetails", "Records in this
FlowFile were invalid for the following reasons: ; "
+ + "The following 1 fields had values whose type did not match
the schema: [/id]");
+ }
+
+ @Test
+ public void testSchemaNameAccessWithBranch() throws Exception {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
+
+ final MockSchemaRegistry registry = new MockSchemaRegistry();
+ registry.addSchema("record", "branch", AvroTypeUtil.createSchema(new
Schema.Parser().parse(schema)));
+ runner.addControllerService("registry", registry);
+ runner.enableControllerService(registry);
+
+ final CSVReader csvReader = new CSVReader();
+ runner.addControllerService("reader", csvReader);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvReader);
+
+ final CSVRecordSetWriter csvWriter = new CSVRecordSetWriter();
+ runner.addControllerService("writer", csvWriter);
+ runner.setProperty(csvWriter, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvWriter, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvWriter);
+
+ final MockRecordWriter invalidWriter = new MockRecordWriter("invalid",
true);
+ runner.addControllerService("invalid-writer", invalidWriter);
+ runner.enableControllerService(invalidWriter);
+
+ runner.setProperty(ValidateRecord.RECORD_READER, "reader");
+ runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
+ runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_NAME_PROPERTY);
+ runner.setProperty(SCHEMA_REGISTRY, "registry");
+ runner.setProperty(SCHEMA_NAME, "record");
+ runner.setProperty(SCHEMA_BRANCH_NAME, "branch");
+ runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
+ runner.setProperty(ValidateRecord.MAX_VALIDATION_DETAILS_LENGTH,
"150");
+ runner.setProperty(ValidateRecord.VALIDATION_DETAILS_ATTRIBUTE_NAME,
"valDetails");
+
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
+ runner.enqueue(content);
+ runner.run();
+
+ runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
+ runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
+
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
+ invalidFlowFile.assertAttributeEquals("record.count", "1");
+ invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
+ invalidFlowFile.assertAttributeExists("valDetails");
+ invalidFlowFile.assertAttributeEquals("valDetails", "Records in this
FlowFile were invalid for the following reasons: ; "
+ + "The following 1 fields had values whose type did not match
the schema: [/id]");
+ }
+
+ @Test
+ public void testSchemaNameAccessWithVersion() throws Exception {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
+
+ final MockSchemaRegistry registry = new MockSchemaRegistry();
+ registry.addSchema("record", 1, AvroTypeUtil.createSchema(new
Schema.Parser().parse(schema)));
+ runner.addControllerService("registry", registry);
+ runner.enableControllerService(registry);
+
+ final CSVReader csvReader = new CSVReader();
+ runner.addControllerService("reader", csvReader);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvReader);
+
+ final CSVRecordSetWriter csvWriter = new CSVRecordSetWriter();
+ runner.addControllerService("writer", csvWriter);
+ runner.setProperty(csvWriter, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvWriter, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvWriter);
+
+ final MockRecordWriter invalidWriter = new MockRecordWriter("invalid",
true);
+ runner.addControllerService("invalid-writer", invalidWriter);
+ runner.enableControllerService(invalidWriter);
+
+ runner.setProperty(ValidateRecord.RECORD_READER, "reader");
+ runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
+ runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_NAME_PROPERTY);
+ runner.setProperty(SCHEMA_REGISTRY, "registry");
+ runner.setProperty(SCHEMA_NAME, "record");
+ runner.setProperty(SCHEMA_VERSION, "1");
+ runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
+ runner.setProperty(ValidateRecord.MAX_VALIDATION_DETAILS_LENGTH,
"150");
+ runner.setProperty(ValidateRecord.VALIDATION_DETAILS_ATTRIBUTE_NAME,
"valDetails");
+
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
+ runner.enqueue(content);
+ runner.run();
+
+ runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
+ runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
+
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
+ invalidFlowFile.assertAttributeEquals("record.count", "1");
+ invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
+ invalidFlowFile.assertAttributeExists("valDetails");
+ invalidFlowFile.assertAttributeEquals("valDetails", "Records in this
FlowFile were invalid for the following reasons: ; "
+ + "The following 1 fields had values whose type did not match
the schema: [/id]");
+ }
+
+ @Test
+ public void testSchemaNameAccessWithBranchAndVersion() throws Exception {
+ final String schema =
Files.readString(Paths.get("src/test/resources/TestUpdateRecord/schema/person-with-name-string.avsc"));
+
+ final MockSchemaRegistry registry = new MockSchemaRegistry();
+ registry.addSchema("record", "branch", 1,
AvroTypeUtil.createSchema(new Schema.Parser().parse(schema)));
+ runner.addControllerService("registry", registry);
+ runner.enableControllerService(registry);
+
+ final CSVReader csvReader = new CSVReader();
+ runner.addControllerService("reader", csvReader);
+ runner.setProperty(csvReader, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvReader, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvReader);
+
+ final CSVRecordSetWriter csvWriter = new CSVRecordSetWriter();
+ runner.addControllerService("writer", csvWriter);
+ runner.setProperty(csvWriter, ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_TEXT_PROPERTY);
+ runner.setProperty(csvWriter, SCHEMA_TEXT, schema);
+ runner.enableControllerService(csvWriter);
+
+ final MockRecordWriter invalidWriter = new MockRecordWriter("invalid",
true);
+ runner.addControllerService("invalid-writer", invalidWriter);
+ runner.enableControllerService(invalidWriter);
+
+ runner.setProperty(ValidateRecord.RECORD_READER, "reader");
+ runner.setProperty(ValidateRecord.RECORD_WRITER, "writer");
+ runner.setProperty(ValidateRecord.INVALID_RECORD_WRITER,
"invalid-writer");
+ runner.setProperty(ValidateRecord.SCHEMA_ACCESS_STRATEGY,
SCHEMA_NAME_PROPERTY);
+ runner.setProperty(SCHEMA_REGISTRY, "registry");
+ runner.setProperty(SCHEMA_NAME, "record");
+ runner.setProperty(SCHEMA_BRANCH_NAME, "branch");
+ runner.setProperty(SCHEMA_VERSION, "1");
+ runner.setProperty(ValidateRecord.ALLOW_EXTRA_FIELDS, "false");
+ runner.setProperty(ValidateRecord.MAX_VALIDATION_DETAILS_LENGTH,
"150");
+ runner.setProperty(ValidateRecord.VALIDATION_DETAILS_ATTRIBUTE_NAME,
"valDetails");
+
+ final String content = """
+ 1, John Doe
+ 2, Jane Doe
+ Three, Jack Doe
+ """;
+ runner.enqueue(content);
+ runner.run();
+
+ runner.assertTransferCount(ValidateRecord.REL_INVALID, 1);
+ runner.assertTransferCount(ValidateRecord.REL_FAILURE, 0);
+
+ final MockFlowFile invalidFlowFile =
runner.getFlowFilesForRelationship(ValidateRecord.REL_INVALID).getFirst();
+ invalidFlowFile.assertAttributeEquals("record.count", "1");
+ invalidFlowFile.assertContentEquals("invalid\n\"Three\",\"Jack
Doe\"\n");
+ invalidFlowFile.assertAttributeExists("valDetails");
+ invalidFlowFile.assertAttributeEquals("valDetails", "Records in this
FlowFile were invalid for the following reasons: ; "
+ + "The following 1 fields had values whose type did not match
the schema: [/id]");
+ }
}