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)),

Reply via email to