This is an automated email from the ASF dual-hosted git repository.
pvillard 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 ff5472456c3 NIFI-9369 Added a 'Retain Unicode Escape Sequences' option
for JoltTransformJSON to allow for retaining Unicode escape sequences. (#11031)
ff5472456c3 is described below
commit ff5472456c376fadd22dadeb6e8c70e750631186
Author: dan-s1 <[email protected]>
AuthorDate: Thu Mar 26 08:08:53 2026 -0400
NIFI-9369 Added a 'Retain Unicode Escape Sequences' option for
JoltTransformJSON to allow for retaining Unicode escape sequences. (#11031)
---
.../nifi/processors/jolt/JoltTransformJSON.java | 21 ++++++++++++-
.../processors/jolt/TestJoltTransformJSON.java | 35 ++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git
a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/main/java/org/apache/nifi/processors/jolt/JoltTransformJSON.java
b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/main/java/org/apache/nifi/processors/jolt/JoltTransformJSON.java
index 7af10398bee..6fa8e810769 100644
---
a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/main/java/org/apache/nifi/processors/jolt/JoltTransformJSON.java
+++
b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/main/java/org/apache/nifi/processors/jolt/JoltTransformJSON.java
@@ -17,6 +17,7 @@
package org.apache.nifi.processors.jolt;
import com.fasterxml.jackson.core.StreamReadConstraints;
+import com.fasterxml.jackson.core.json.JsonWriteFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.joltcommunity.jolt.JoltTransform;
import io.joltcommunity.jolt.JsonUtil;
@@ -112,6 +113,15 @@ public class JoltTransformJSON extends
AbstractJoltTransform {
.addValidator(StandardValidators.DATA_SIZE_VALIDATOR)
.build();
+ public static final PropertyDescriptor RETAIN_UNICODE_ESCAPE_SEQUENCES =
new PropertyDescriptor.Builder()
+ .name("Retain Unicode Escape Sequences")
+ .description("Allows for retaining Unicode escape sequences
instead of resolving them (e.g. retain text \\u00E9 without resolving to é)")
+ .required(true)
+ .defaultValue("false")
+ .allowableValues("true", "false")
+ .addValidator(StandardValidators.BOOLEAN_VALIDATOR)
+ .build();
+
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")
.description("The FlowFile with successfully transformed content
or updated attribute will be routed to this relationship")
@@ -127,7 +137,8 @@ public class JoltTransformJSON extends
AbstractJoltTransform {
JSON_SOURCE,
JSON_SOURCE_ATTRIBUTE,
PRETTY_PRINT,
- MAX_STRING_LENGTH
+ MAX_STRING_LENGTH,
+ RETAIN_UNICODE_ESCAPE_SEQUENCES
)
).toList();
@@ -160,6 +171,14 @@ public class JoltTransformJSON extends
AbstractJoltTransform {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getFactory().setStreamReadConstraints(streamReadConstraints);
+
+ final boolean retainUnicodeEscapeSequences =
context.getProperty(RETAIN_UNICODE_ESCAPE_SEQUENCES).asBoolean();
+ if (retainUnicodeEscapeSequences) {
+
objectMapper.getFactory().enable(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature());
+ } else {
+
objectMapper.getFactory().disable(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature());
+ }
+
jsonUtil = JsonUtils.customJsonUtil(objectMapper);
configuredClassLoader = getClass().getClassLoader();
diff --git
a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/test/java/org/apache/nifi/processors/jolt/TestJoltTransformJSON.java
b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/test/java/org/apache/nifi/processors/jolt/TestJoltTransformJSON.java
index 42b333c94f8..8efe2e9db92 100644
---
a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/test/java/org/apache/nifi/processors/jolt/TestJoltTransformJSON.java
+++
b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-processors/src/test/java/org/apache/nifi/processors/jolt/TestJoltTransformJSON.java
@@ -580,6 +580,41 @@ class TestJoltTransformJSON {
runner.assertAllFlowFilesTransferred(JoltTransformJSON.REL_FAILURE);
}
+ @ParameterizedTest
+ @MethodSource("unicodeEscaping")
+ void testWithUnicodeEscaping(boolean retainUnicodeEscapeSequences, String
expectedText) {
+ final String unicodeJson = """
+ {"value":
"\\u011f\\u00fc\\u015f\\u0131\\u00f6\\u00e7\\u011e\\u00dc\\u015e\\u0130\\u00d6\\u00c7"}""";
+ final String passThroughSpec = """
+ [
+ {
+ "operation": "shift",
+ "spec": {
+ "*": "&"
+ }
+ }
+ ]""";
+
+ runner.setProperty(JoltTransformJSON.JOLT_SPEC, passThroughSpec);
+ runner.setProperty(JoltTransformJSON.RETAIN_UNICODE_ESCAPE_SEQUENCES,
Boolean.toString(retainUnicodeEscapeSequences));
+ runner.enqueue(unicodeJson);
+ runner.run();
+
+ runner.assertAllFlowFilesTransferred(JoltTransformJSON.REL_SUCCESS);
+ final MockFlowFile transformed =
runner.getFlowFilesForRelationship(JoltTransformJSON.REL_SUCCESS).getFirst();
+ // NOTE: The JSON specification allows for both uppercase and
lowercase hexadecimal letters.
+ // Jackson seems to prefer to upper case them hence must test with
case insensitivity when unicode escape sequence is retained.
+
assertTrue(transformed.getContent().toLowerCase().contains(expectedText.toLowerCase()));
+ }
+
+ private static Stream<Arguments> unicodeEscaping() {
+ return Stream.of(
+ Arguments.argumentSet("Retain Unicode Escape Sequence", true,
"\\u011f\\u00fc\\u015f\\u0131\\u00f6\\u00e7\\u011e\\u00dc\\u015e\\u0130\\u00d6\\u00c7"),
+ Arguments.argumentSet("Resolve Unicode Escape Sequence",
false, "ğüşıöçĞÜŞİÖÇ")
+
+ );
+ }
+
private static Stream<Arguments> getChainrArguments() {
return Stream.of(
Arguments.argumentSet("has no single line comments",
Paths.get(CHAINR_SPEC_PATH)),