dan-s1 commented on code in PR #8417:
URL: https://github.com/apache/nifi/pull/8417#discussion_r1503439274
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncodeContent.java:
##########
@@ -29,55 +37,88 @@
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.Validator;
+import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.io.StreamCallback;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.processors.standard.encoding.EncodingMode;
+import org.apache.nifi.processors.standard.encoding.EncodingType;
+import org.apache.nifi.processors.standard.encoding.LineOutputMode;
import org.apache.nifi.processors.standard.util.ValidatingBase32InputStream;
import org.apache.nifi.processors.standard.util.ValidatingBase64InputStream;
import org.apache.nifi.stream.io.StreamUtils;
import org.apache.nifi.util.StopWatch;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
@SideEffectFree
@SupportsBatching
@InputRequirement(Requirement.INPUT_REQUIRED)
@Tags({"encode", "decode", "base64", "base32", "hex"})
@CapabilityDescription("Encode or decode the contents of a FlowFile using
Base64, Base32, or hex encoding schemes")
public class EncodeContent extends AbstractProcessor {
- public static final String ENCODE_MODE = "Encode";
- public static final String DECODE_MODE = "Decode";
-
- public static final String BASE64_ENCODING = "base64";
- public static final String BASE32_ENCODING = "base32";
- public static final String HEX_ENCODING = "hex";
-
public static final PropertyDescriptor MODE = new
PropertyDescriptor.Builder()
.name("Mode")
.description("Specifies whether the content should be encoded or
decoded")
.required(true)
- .allowableValues(ENCODE_MODE, DECODE_MODE)
- .defaultValue(ENCODE_MODE)
+ .allowableValues(EncodingMode.class)
+ .defaultValue(EncodingMode.ENCODE)
.build();
public static final PropertyDescriptor ENCODING = new
PropertyDescriptor.Builder()
.name("Encoding")
.description("Specifies the type of encoding used")
.required(true)
- .allowableValues(BASE64_ENCODING, BASE32_ENCODING, HEX_ENCODING)
- .defaultValue(BASE64_ENCODING)
+ .allowableValues(EncodingType.class)
+ .defaultValue(EncodingType.BASE64_ENCODING)
+ .build();
+
+ static final PropertyDescriptor LINE_OUTPUT_MODE = new
PropertyDescriptor.Builder()
+ .name("line-output-mode")
+ .displayName("Line Output Mode")
+ .description("If set to 'single-line', the encoded FlowFile
content will output as a single line. If set to 'multiple-lines', "
+ + "it will output as multiple lines. This property is only
applicable when Base64 or Base32 encoding is selected.")
+ .required(false)
+ .defaultValue(LineOutputMode.SINGLE_LINE)
+ .allowableValues(LineOutputMode.class)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(MODE, EncodingMode.ENCODE)
+ .dependsOn(ENCODING, EncodingType.BASE64_ENCODING,
EncodingType.BASE32_ENCODING)
.build();
+ static final PropertyDescriptor ENCODED_LINE_SEPARATOR = new
PropertyDescriptor.Builder()
+ .name("line-separator")
Review Comment:
```suggestion
.name("Encoded Content Line Separator")
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncodeContent.java:
##########
@@ -112,9 +153,14 @@ public void onTrigger(final ProcessContext context, final
ProcessSession session
return;
}
- final boolean encode =
context.getProperty(MODE).getValue().equalsIgnoreCase(ENCODE_MODE);
- final String encoding = context.getProperty(ENCODING).getValue();
- final StreamCallback callback = getStreamCallback(encode, encoding);
+ final boolean encode =
context.getProperty(MODE).getValue().equals(EncodingMode.ENCODE.getValue());
+ final EncodingType encoding =
EncodingType.valueOf(context.getProperty(ENCODING).getValue());
+
+ final Boolean singleLineOutput =
context.getProperty(LINE_OUTPUT_MODE).getValue().equals(LineOutputMode.SINGLE_LINE.getValue());
Review Comment:
```suggestion
final boolean singleLineOutput =
context.getProperty(LINE_OUTPUT_MODE).getValue().equals(LineOutputMode.SINGLE_LINE.getValue());
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncodeContent.java:
##########
@@ -29,55 +37,88 @@
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.Validator;
+import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.io.StreamCallback;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.processors.standard.encoding.EncodingMode;
+import org.apache.nifi.processors.standard.encoding.EncodingType;
+import org.apache.nifi.processors.standard.encoding.LineOutputMode;
import org.apache.nifi.processors.standard.util.ValidatingBase32InputStream;
import org.apache.nifi.processors.standard.util.ValidatingBase64InputStream;
import org.apache.nifi.stream.io.StreamUtils;
import org.apache.nifi.util.StopWatch;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
@SideEffectFree
@SupportsBatching
@InputRequirement(Requirement.INPUT_REQUIRED)
@Tags({"encode", "decode", "base64", "base32", "hex"})
@CapabilityDescription("Encode or decode the contents of a FlowFile using
Base64, Base32, or hex encoding schemes")
public class EncodeContent extends AbstractProcessor {
- public static final String ENCODE_MODE = "Encode";
- public static final String DECODE_MODE = "Decode";
-
- public static final String BASE64_ENCODING = "base64";
- public static final String BASE32_ENCODING = "base32";
- public static final String HEX_ENCODING = "hex";
-
public static final PropertyDescriptor MODE = new
PropertyDescriptor.Builder()
.name("Mode")
.description("Specifies whether the content should be encoded or
decoded")
.required(true)
- .allowableValues(ENCODE_MODE, DECODE_MODE)
- .defaultValue(ENCODE_MODE)
+ .allowableValues(EncodingMode.class)
+ .defaultValue(EncodingMode.ENCODE)
.build();
public static final PropertyDescriptor ENCODING = new
PropertyDescriptor.Builder()
.name("Encoding")
.description("Specifies the type of encoding used")
.required(true)
- .allowableValues(BASE64_ENCODING, BASE32_ENCODING, HEX_ENCODING)
- .defaultValue(BASE64_ENCODING)
+ .allowableValues(EncodingType.class)
+ .defaultValue(EncodingType.BASE64_ENCODING)
+ .build();
+
+ static final PropertyDescriptor LINE_OUTPUT_MODE = new
PropertyDescriptor.Builder()
+ .name("line-output-mode")
Review Comment:
```suggestion
.name("Line Output Mode")
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -70,96 +102,310 @@ public void testFailDecodeNotBase64() throws IOException {
}
@Test
- public void testFailDecodeNotBase64ButIsAMultipleOfFourBytes() {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ void testEncodeDecodeSpecialCharsBase64() {
+ final String specialChars = "!@#$%^&*()_+{}:\"<>?[];',./~`-=";
+ final String expectedOutput =
"IUAjJCVeJiooKV8re306Ijw+P1tdOycsLi9+YC09" + System.lineSeparator();
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE64_ENCODING);
-
- testRunner.enqueue("four@@@@multiple".getBytes());
- testRunner.clearTransferState();
- testRunner.run();
+ executeTestSuccessHelper(EncodingMode.ENCODE,
EncodingType.BASE64_ENCODING, specialChars, expectedOutput);
+ testRunner.clearTransferState(); // clear the state for the next test
+ executeTestSuccessHelper(EncodingMode.DECODE,
EncodingType.BASE64_ENCODING, expectedOutput, specialChars);
+ }
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_FAILURE, 1);
+ @ParameterizedTest
+ @MethodSource("encodeBase32Args")
+ void testBasicDecodeBase32(final String input, final String
expectedOutput) {
+ // we'll use the same args from `encodeBase32Args`, only flip around
input and output
+ executeTestSuccessHelper(EncodingMode.DECODE,
EncodingType.BASE32_ENCODING, expectedOutput, input);
}
- @Test
- public void testBase32RoundTrip() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ @ParameterizedTest
+ @MethodSource("encodeBase64Args")
+ void testBasicDecodeBase64(final String input, final String
expectedOutput) {
+ // we'll use the same args from `encodeBase64Args`, only flip around
input and output
+ executeTestSuccessHelper(EncodingMode.DECODE,
EncodingType.BASE64_ENCODING, expectedOutput, input);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.ENCODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE32_ENCODING);
+ @ParameterizedTest
+ @MethodSource("encodeHexArgs")
+ void testBasicDecodeHex(final String input, final String expectedOutput) {
+ // we'll use the same args from `encodeHexArgs`, only flip around
input and output
+ executeTestSuccessHelper(EncodingMode.DECODE,
EncodingType.HEX_ENCODING, expectedOutput, input);
+ }
- testRunner.enqueue(FILE_PATH);
- testRunner.clearTransferState();
- testRunner.run();
+ @ParameterizedTest
+ @MethodSource("encodeHexArgs")
+ void testBasicEncodeHex(final String input, final String expectedOutput) {
+ executeTestSuccessHelper(EncodingMode.ENCODE,
EncodingType.HEX_ENCODING, input, expectedOutput);
+ }
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_SUCCESS, 1);
+ private static Stream<Arguments> encodeHexArgs() {
+ return Stream.of(
+ Arguments.of("hello", "68656C6C6F"),
+ Arguments.of("foo", "666F6F"),
+ Arguments.of("你好", "E4BDA0E5A5BD"),
+ Arguments.of("Здравствуйте",
"D097D0B4D180D0B0D0B2D181D182D0B2D183D0B9D182D0B5")
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("encodeBase32Args")
+ void testBasicEncodeBase32(final String input, final String
expectedOutput) {
+ executeTestSuccessHelper(EncodingMode.ENCODE,
EncodingType.BASE32_ENCODING, input, expectedOutput);
+ }
- MockFlowFile flowFile =
testRunner.getFlowFilesForRelationship(EncodeContent.REL_SUCCESS).get(0);
- testRunner.assertQueueEmpty();
+ private static Stream<Arguments> encodeBase32Args() {
+ return Stream.of(
+ Arguments.of("hello", "NBSWY3DP" + System.lineSeparator()),
+ Arguments.of("foo", "MZXW6===" + System.lineSeparator()),
+ Arguments.of("你好", "4S62BZNFXU======" + System.lineSeparator()),
+ Arguments.of("Здравствуйте",
"2CL5BNGRQDILBUFS2GA5DAWQWLIYHUFZ2GBNBNI=" + System.lineSeparator())
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("encodeBase64Args")
+ void testBasicEncodeBase64(final String input, final String
expectedOutput) {
+ executeTestSuccessHelper(EncodingMode.ENCODE,
EncodingType.BASE64_ENCODING, input, expectedOutput);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.enqueue(flowFile);
- testRunner.clearTransferState();
- testRunner.run();
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_SUCCESS, 1);
+ private static Stream<Arguments> encodeBase64Args() {
+ return Stream.of(
+ Arguments.of("hello", "aGVsbG8=" + System.lineSeparator()),
+ Arguments.of("foo", "Zm9v" + System.lineSeparator()),
+ Arguments.of("你好", "5L2g5aW9" + System.lineSeparator()),
+ Arguments.of("Здравствуйте", "0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1"
+ System.lineSeparator())
+ );
+ }
- flowFile =
testRunner.getFlowFilesForRelationship(EncodeContent.REL_SUCCESS).get(0);
- flowFile.assertContentEquals(FILE_PATH);
+ @Test
+ void testBlankValueShouldNotFail() {
+ executeTestSuccessHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ StringUtils.EMPTY,
+ StringUtils.EMPTY);
}
@Test
- public void testFailDecodeNotBase32() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ void testEncodeContentMultipleLinesBase64() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg"
+ System.lineSeparator()
+ +
"c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu"
+ System.lineSeparator()
+ + "YSBhbGlxdWEu" + System.lineSeparator();
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES,
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE32_ENCODING);
+ @Test
+ void testEncodeContentSingleLineBase64() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg"
+ +
"c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu"
+ + "YSBhbGlxdWEu";
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.SINGLE_LINE,
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.enqueue(FILE_PATH);
- testRunner.clearTransferState();
- testRunner.run();
+ @Test
+ void testEncodeContentSingleLineBase32() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4RAMFSGS4DJONRWS3THEBSWY2LUF"
+ +
"QQHGZLEEBSG6IDFNF2XG3LPMQQHIZLNOBXXEIDJNZRWSZDJMR2W45BAOV2CA3DBMJXXEZJAMV2CAZDPNRXXEZJANVQWO3TBEBQWY2LROVQS4===";
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE32_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.SINGLE_LINE,
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_FAILURE, 1);
+ @Test
+ void testEncodeContentMultipleLinesBase32() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4RAMFSGS4DJ" +
System.lineSeparator()
+ +
"ONRWS3THEBSWY2LUFQQHGZLEEBSG6IDFNF2XG3LPMQQHIZLNOBXXEIDJNZRWSZDJMR2W45BA" +
System.lineSeparator()
+ + "OV2CA3DBMJXXEZJAMV2CAZDPNRXXEZJANVQWO3TBEBQWY2LROVQS4===" +
System.lineSeparator();
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE32_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES, // set false to output multiple
lines
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
}
@Test
- public void testHexRoundTrip() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ void testEncodeContentMultipleLinesNonStandardLengthBase32() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4RAMFSGS4DJONRWS3TH"
+ System.lineSeparator()
+ +
"EBSWY2LUFQQHGZLEEBSG6IDFNF2XG3LPMQQHIZLNOBXXEIDJNZRWSZDJMR2W45BAOV2CA3DBMJXXEZJA"
+ System.lineSeparator()
+ + "MV2CAZDPNRXXEZJANVQWO3TBEBQWY2LROVQS4===" +
System.lineSeparator();
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE32_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES,
+ 80,
+ System.lineSeparator(),
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.ENCODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.HEX_ENCODING);
+ @Test
+ void testThatLineLengthIsIgnoredIfSingleLineOutputTrueBase32() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4RAMFSGS4DJONRWS3THEBSWY2LUFQQHGZLEEB"
+ +
"SG6IDFNF2XG3LPMQQHIZLNOBXXEIDJNZRWSZDJMR2W45BAOV2CA3DBMJXXEZJAMV2CAZDPNRXXEZJANVQWO3TBEBQWY2LROVQS4===";
+
+ // Setting a low value for `lineLength` but single line true ensures
that `lineLength` is ignored
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE32_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.SINGLE_LINE,
+ 2, // set a low value >= 0
+ System.lineSeparator(),
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.enqueue(FILE_PATH);
- testRunner.clearTransferState();
- testRunner.run();
+ @Test
+ void testEncodeContentMultipleLinesNonStandardLengthBase64() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2Vk"
+ System.lineSeparator()
+ +
"IGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlx"
+ System.lineSeparator()
+ + "dWEu" + System.lineSeparator();
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES, // set false to output multiple
lines
+ 80,
+ System.lineSeparator(),
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_SUCCESS, 1);
+ @Test
+ void testOverrideLineSeparatorBase64() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2Vk"
+ "|"
+ +
"IGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlx"
+ "|"
+ + "dWEu" + "|";
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES, // set false to output multiple
lines
+ 80,
+ "|",
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- MockFlowFile flowFile =
testRunner.getFlowFilesForRelationship(EncodeContent.REL_SUCCESS).get(0);
- testRunner.assertQueueEmpty();
+ @Test
+ void testOverrideLineSeparatorBase32() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4RAMFSGS4DJONRWS3TH"
+ "|"
+ +
"EBSWY2LUFQQHGZLEEBSG6IDFNF2XG3LPMQQHIZLNOBXXEIDJNZRWSZDJMR2W45BAOV2CA3DBMJXXEZJA"
+ "|"
+ + "MV2CAZDPNRXXEZJANVQWO3TBEBQWY2LROVQS4===" + "|";
+
+ // Execute the test using the helper method
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE32_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.MULTIPLE_LINES, // set false to output multiple
lines
+ 80,
+ "|",
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.enqueue(flowFile);
- testRunner.clearTransferState();
- testRunner.run();
- testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_SUCCESS, 1);
+ @Test
+ void testThatLineLengthIsIgnoredIfSingleLineOutputTrueBase64() {
+ // this input is greater than 57 bytes, sure to generate multiple
lines in base64
+ final String expectedOutput =
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg"
+ +
"c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu"
+ + "YSBhbGlxdWEu";
+
+ // Setting a low value for `lineLength` but single line true ensures
that `lineLength` is ignored
+ executeTestHelper(EncodingMode.ENCODE,
+ EncodingType.BASE64_ENCODING,
+ LOREM_IPSUM,
+ LineOutputMode.SINGLE_LINE, // set true to output single line
+ 2, // set a low value >= 0
+ System.lineSeparator(),
+ expectedOutput,
+ EncodeContent.REL_SUCCESS);
+ }
- flowFile =
testRunner.getFlowFilesForRelationship(EncodeContent.REL_SUCCESS).get(0);
- flowFile.assertContentEquals(FILE_PATH);
+ private void executeTestSuccessHelper(final DescribedValue mode,
+ final DescribedValue encodingType,
+ final String input,
+ final String expectedOutput) {
+ executeTestSuccessHelper(mode, encodingType, input,
LineOutputMode.MULTIPLE_LINES, expectedOutput);
}
- @Test
- public void testFailDecodeNotHex() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ private void executeTestSuccessHelper(final DescribedValue mode,
+ final DescribedValue encodingType,
+ final String input,
+ final DescribedValue outputToSingleLine,
+ final String expectedOutput) {
+ executeTestHelper(mode, encodingType, input, outputToSingleLine,
expectedOutput, EncodeContent.REL_SUCCESS);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.HEX_ENCODING);
+ private void executeTestHelper(final DescribedValue mode,
+ final DescribedValue encodingType,
+ final String input,
+ final DescribedValue outputToSingleLine,
+ final String expectedOutput,
+ final Relationship routedTo) {
+ executeTestHelper(mode,
+ encodingType,
+ input,
+ outputToSingleLine,
+ 76,
+ System.lineSeparator(),
+ expectedOutput,
+ routedTo);
+ }
- testRunner.enqueue(FILE_PATH);
- testRunner.clearTransferState();
+ private void executeTestHelper(final DescribedValue mode,
+ final DescribedValue encodingType,
+ final String input,
+ final DescribedValue outputToSingleLine,
+ final Integer lineLength,
+ final String lineSeparator,
+ final String expectedOutput,
+ final Relationship routedTo) {
+
+ testRunner.setProperty(EncodeContent.MODE, mode.getValue());
+ testRunner.setProperty(EncodeContent.ENCODING,
encodingType.getValue());
+ testRunner.setProperty(EncodeContent.LINE_OUTPUT_MODE,
outputToSingleLine.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.MODE, mode);
testRunner.setProperty(EncodeContent.ENCODING, encodingType);
testRunner.setProperty(EncodeContent.LINE_OUTPUT_MODE,
outputToSingleLine);
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -45,7 +78,7 @@ public void testBase64RoundTrip() throws IOException {
MockFlowFile flowFile =
testRunner.getFlowFilesForRelationship(EncodeContent.REL_SUCCESS).get(0);
testRunner.assertQueueEmpty();
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.DECODE.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.MODE, EncodingMode.DECODE);
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncodeContent.java:
##########
@@ -29,55 +37,88 @@
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.Validator;
+import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.io.StreamCallback;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.processors.standard.encoding.EncodingMode;
+import org.apache.nifi.processors.standard.encoding.EncodingType;
+import org.apache.nifi.processors.standard.encoding.LineOutputMode;
import org.apache.nifi.processors.standard.util.ValidatingBase32InputStream;
import org.apache.nifi.processors.standard.util.ValidatingBase64InputStream;
import org.apache.nifi.stream.io.StreamUtils;
import org.apache.nifi.util.StopWatch;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
@SideEffectFree
@SupportsBatching
@InputRequirement(Requirement.INPUT_REQUIRED)
@Tags({"encode", "decode", "base64", "base32", "hex"})
@CapabilityDescription("Encode or decode the contents of a FlowFile using
Base64, Base32, or hex encoding schemes")
public class EncodeContent extends AbstractProcessor {
- public static final String ENCODE_MODE = "Encode";
- public static final String DECODE_MODE = "Decode";
-
- public static final String BASE64_ENCODING = "base64";
- public static final String BASE32_ENCODING = "base32";
- public static final String HEX_ENCODING = "hex";
-
public static final PropertyDescriptor MODE = new
PropertyDescriptor.Builder()
.name("Mode")
.description("Specifies whether the content should be encoded or
decoded")
.required(true)
- .allowableValues(ENCODE_MODE, DECODE_MODE)
- .defaultValue(ENCODE_MODE)
+ .allowableValues(EncodingMode.class)
+ .defaultValue(EncodingMode.ENCODE)
.build();
public static final PropertyDescriptor ENCODING = new
PropertyDescriptor.Builder()
.name("Encoding")
.description("Specifies the type of encoding used")
.required(true)
- .allowableValues(BASE64_ENCODING, BASE32_ENCODING, HEX_ENCODING)
- .defaultValue(BASE64_ENCODING)
+ .allowableValues(EncodingType.class)
+ .defaultValue(EncodingType.BASE64_ENCODING)
+ .build();
+
+ static final PropertyDescriptor LINE_OUTPUT_MODE = new
PropertyDescriptor.Builder()
+ .name("line-output-mode")
+ .displayName("Line Output Mode")
+ .description("If set to 'single-line', the encoded FlowFile
content will output as a single line. If set to 'multiple-lines', "
+ + "it will output as multiple lines. This property is only
applicable when Base64 or Base32 encoding is selected.")
+ .required(false)
+ .defaultValue(LineOutputMode.SINGLE_LINE)
+ .allowableValues(LineOutputMode.class)
+ .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+ .dependsOn(MODE, EncodingMode.ENCODE)
+ .dependsOn(ENCODING, EncodingType.BASE64_ENCODING,
EncodingType.BASE32_ENCODING)
.build();
+ static final PropertyDescriptor ENCODED_LINE_SEPARATOR = new
PropertyDescriptor.Builder()
+ .name("line-separator")
+ .displayName("Encoded Content Line Separator")
+ .description("Each line of encoded data will be terminated with this
byte sequence (e.g. \\r\\n"
+ + "). This property defaults to the system-dependent line
separator string. If `line-length` <= 0, "
+ + "the `line-separator` property is not used. This property is
not used for `hex` encoding.")
+ .required(false)
+
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+ .defaultValue(System.lineSeparator())
+ .addValidator(Validator.VALID)
+ .dependsOn(MODE, EncodingMode.ENCODE)
+ .dependsOn(ENCODING, EncodingType.BASE64_ENCODING,
EncodingType.BASE32_ENCODING)
+ .build();
+
+ static final PropertyDescriptor ENCODED_LINE_LENGTH = new
PropertyDescriptor.Builder()
+ .name("encoded-line-length")
Review Comment:
```suggestion
.name("Encoded Content Line Length")
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -55,12 +88,11 @@ public void testBase64RoundTrip() throws IOException {
flowFile.assertContentEquals(FILE_PATH);
}
- @Test
- public void testFailDecodeNotBase64() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
-
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE64_ENCODING);
+ @ParameterizedTest
+ @EnumSource(value = EncodingType.class)
+ void testDecodeFailure(final EncodingType encoding) throws IOException {
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.DECODE.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.MODE, EncodingMode.DECODE);
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -55,12 +88,11 @@ public void testBase64RoundTrip() throws IOException {
flowFile.assertContentEquals(FILE_PATH);
}
- @Test
- public void testFailDecodeNotBase64() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
-
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.DECODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE64_ENCODING);
+ @ParameterizedTest
+ @EnumSource(value = EncodingType.class)
+ void testDecodeFailure(final EncodingType encoding) throws IOException {
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.DECODE.getValue());
+ testRunner.setProperty(EncodeContent.ENCODING, encoding.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.ENCODING, encoding);
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncodeContent.java:
##########
@@ -112,9 +153,14 @@ public void onTrigger(final ProcessContext context, final
ProcessSession session
return;
}
- final boolean encode =
context.getProperty(MODE).getValue().equalsIgnoreCase(ENCODE_MODE);
- final String encoding = context.getProperty(ENCODING).getValue();
- final StreamCallback callback = getStreamCallback(encode, encoding);
+ final boolean encode =
context.getProperty(MODE).getValue().equals(EncodingMode.ENCODE.getValue());
+ final EncodingType encoding =
EncodingType.valueOf(context.getProperty(ENCODING).getValue());
+
Review Comment:
```suggestion
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -16,25 +16,58 @@
*/
package org.apache.nifi.processors.standard;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.stream.Stream;
+import org.apache.nifi.components.DescribedValue;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processors.standard.encoding.EncodingMode;
+import org.apache.nifi.processors.standard.encoding.EncodingType;
+import org.apache.nifi.processors.standard.encoding.LineOutputMode;
import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.StringUtils;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class TestEncodeContent {
-public class TestEncodeContent {
+ private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.";
private static final Path FILE_PATH =
Paths.get("src/test/resources/hello.txt");
+ private TestRunner testRunner;
+
+ @BeforeEach
+ void setUp() {
+ testRunner = TestRunners.newTestRunner(EncodeContent.class);
+ }
@Test
- public void testBase64RoundTrip() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ void testFailDecodeNotBase64ButIsAMultipleOfFourBytes() {
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.DECODE.getValue());
+ testRunner.setProperty(EncodeContent.ENCODING,
EncodingType.BASE64_ENCODING.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.MODE, EncodingMode.DECODE);
testRunner.setProperty(EncodeContent.ENCODING,
EncodingType.BASE64_ENCODING);
```
##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEncodeContent.java:
##########
@@ -16,25 +16,58 @@
*/
package org.apache.nifi.processors.standard;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.stream.Stream;
+import org.apache.nifi.components.DescribedValue;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processors.standard.encoding.EncodingMode;
+import org.apache.nifi.processors.standard.encoding.EncodingType;
+import org.apache.nifi.processors.standard.encoding.LineOutputMode;
import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.StringUtils;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class TestEncodeContent {
-public class TestEncodeContent {
+ private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.";
private static final Path FILE_PATH =
Paths.get("src/test/resources/hello.txt");
+ private TestRunner testRunner;
+
+ @BeforeEach
+ void setUp() {
+ testRunner = TestRunners.newTestRunner(EncodeContent.class);
+ }
@Test
- public void testBase64RoundTrip() throws IOException {
- final TestRunner testRunner = TestRunners.newTestRunner(new
EncodeContent());
+ void testFailDecodeNotBase64ButIsAMultipleOfFourBytes() {
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.DECODE.getValue());
+ testRunner.setProperty(EncodeContent.ENCODING,
EncodingType.BASE64_ENCODING.getValue());
+
+ testRunner.enqueue("four@@@@multiple".getBytes());
+ testRunner.clearTransferState();
+ testRunner.run();
+
+ testRunner.assertAllFlowFilesTransferred(EncodeContent.REL_FAILURE, 1);
+ }
- testRunner.setProperty(EncodeContent.MODE, EncodeContent.ENCODE_MODE);
- testRunner.setProperty(EncodeContent.ENCODING,
EncodeContent.BASE64_ENCODING);
+ @ParameterizedTest
+ @EnumSource(value = EncodingType.class)
+ void testRoundTrip(final EncodingType encoding) throws IOException {
+ testRunner.setProperty(EncodeContent.MODE,
EncodingMode.ENCODE.getValue());
+ testRunner.setProperty(EncodeContent.ENCODING, encoding.getValue());
Review Comment:
```suggestion
testRunner.setProperty(EncodeContent.MODE, EncodingMode.ENCODE);
testRunner.setProperty(EncodeContent.ENCODING, encoding);
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]