Skip to content

Commit baaabc7

Browse files
NIFI-14504 Fixed Record Field Conversion from Array to String
- Updated Object Array handling to support types other than byte primitives
1 parent 40bb150 commit baaabc7

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/field/ObjectStringFieldConverter.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.time.ZoneId;
2828
import java.time.ZonedDateTime;
2929
import java.time.format.DateTimeFormatter;
30+
import java.util.Arrays;
3031
import java.util.Date;
3132
import java.util.Optional;
3233

@@ -98,14 +99,19 @@ public String convertField(final Object field, final Optional<String> pattern, f
9899
}
99100
case Object[] objectArray -> {
100101
if (objectArray.length > 0) {
101-
final byte[] converted = new byte[objectArray.length];
102-
for (int i = 0; i < objectArray.length; i++) {
103-
converted[i] = (byte) objectArray[i];
102+
final Object firstElement = objectArray[0];
103+
104+
if (firstElement instanceof Byte) {
105+
final byte[] converted = new byte[objectArray.length];
106+
for (int i = 0; i < objectArray.length; i++) {
107+
converted[i] = (byte) objectArray[i];
108+
}
109+
return new String(converted, StandardCharsets.UTF_8);
110+
} else {
111+
return Arrays.toString(objectArray);
104112
}
105-
return new String(converted, StandardCharsets.UTF_8);
106113
} else {
107-
// Handle an empty array as an empty string
108-
return "";
114+
return Arrays.toString(objectArray);
109115
}
110116
}
111117
default -> {

nifi-commons/nifi-record/src/test/java/org/apache/nifi/serialization/record/field/ObjectStringFieldConverterTest.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ class ObjectStringFieldConverterTest {
4646

4747
private static final String DATE_TIME_ZONE_OFFSET_PATTERN = "yyyy-MM-dd HH:mm:ssZZZZZ";
4848

49-
private static final String EMPTY_STRING = "";
49+
private static final String EMPTY_ARRAY_STRING = "[]";
50+
51+
private static final String ARRAY_STRING_ELEMENT = String.class.getSimpleName();
52+
53+
private static final String ARRAY_STRING = "[String, String, String]";
5054

5155
@Test
5256
void testConvertFieldNull() {
@@ -124,7 +128,7 @@ void testConvertFieldDateZoneOffsetPattern() {
124128
}
125129

126130
@Test
127-
void testConvertFieldObjectArray() {
131+
void testConvertFieldObjectArrayOfBytes() {
128132
final String expected = String.class.getSimpleName();
129133
final byte[] bytes = expected.getBytes(StandardCharsets.UTF_8);
130134

@@ -137,12 +141,21 @@ void testConvertFieldObjectArray() {
137141
assertEquals(expected, string);
138142
}
139143

144+
@Test
145+
void testConvertFieldObjectArrayOfStrings() {
146+
final Object[] objectArray = new Object[]{ARRAY_STRING_ELEMENT, ARRAY_STRING_ELEMENT, ARRAY_STRING_ELEMENT};
147+
148+
final String string = CONVERTER.convertField(objectArray, Optional.empty(), FIELD_NAME);
149+
150+
assertEquals(ARRAY_STRING, string);
151+
}
152+
140153
@Test
141154
void testConvertFieldObjectArrayEmpty() {
142155
final Object[] objectArray = new Object[0];
143156

144157
final String string = CONVERTER.convertField(objectArray, Optional.empty(), FIELD_NAME);
145-
assertEquals(EMPTY_STRING, string);
158+
assertEquals(EMPTY_ARRAY_STRING, string);
146159
}
147160

148161
private String getDateTimeZoneOffset() {

nifi-extension-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/test/java/org/apache/nifi/json/TestJsonTreeRowRecordReader.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,35 @@ public void testMultipleInputRecordsWithStartingFieldArray() throws Exception {
759759
assertEquals(List.of("1", "2", "3", "4"), ids);
760760
}
761761

762+
@Test
763+
public void testArrayOfStringsToString() throws Exception {
764+
final String inputJson = """
765+
[{
766+
"labels": [
767+
"first", "second", "third"
768+
]
769+
}]""";
770+
771+
final String labelsFieldName = "labels";
772+
final RecordSchema recordSchema = new SimpleRecordSchema(List.of(
773+
new RecordField(labelsFieldName, RecordFieldType.STRING.getDataType())
774+
));
775+
776+
final StringBuilder labelsRead = new StringBuilder();
777+
try (final InputStream in = new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8));
778+
final JsonTreeRowRecordReader reader = createJsonTreeRowRecordReader(in, recordSchema, dateFormat, timeFormat, timestampFormat,
779+
StartingFieldStrategy.ROOT_NODE, null, SchemaApplicationStrategy.SELECTED_PART, null, false, null)
780+
) {
781+
final Record record = reader.nextRecord();
782+
assertNotNull(record, "Record not found");
783+
784+
final String labels = record.getAsString(labelsFieldName);
785+
labelsRead.append(labels);
786+
}
787+
788+
assertEquals("[first, second, third]", labelsRead.toString());
789+
}
790+
762791
@Test
763792
public void testMultipleInputRecordsWithStartingFieldSingleObject() throws Exception {
764793
final String inputJson = """

0 commit comments

Comments
 (0)