Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Csv codec (3.2.0)
# Csv codec (3.2.1)
## Description
Designed for decode csv raw messages from csv reader to the parsed messages.

Expand Down Expand Up @@ -105,7 +105,11 @@ spec:

## Release notes

### 3.1.0
### 3.2.1

+ fixed: last array-field as simple value

### 3.2.0

+ new length validation parameter
+ array support, to specify array need to have empty header for each value [^array]
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
release_version = 3.2.0
release_version = 3.2.1

docker_image_name=
33 changes: 20 additions & 13 deletions src/main/java/com/exactpro/th2/codec/csv/CsvCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,30 +174,37 @@ private void decodeCsvData(Collection<ErrorHolder> errors, MessageGroup.Builder

int headerLength = header.length;
int rowLength = strings.length;
for (int i = 0; i < headerLength && i < rowLength; i++) {
int extraLength = getGetExtraLength(i, header, rowLength);
if (extraLength == 0) {
for (int i = 0; i < headerLength && i < rowLength; ) {
int extraLength = getHeaderArrayLength(header, i);
if (extraLength == 1) {
builder.putFields(header[i], ValueUtils.toValue(strings[i]));
i++;
} else {
String[] values = new String[extraLength + 1];
System.arraycopy(strings, i, values, 0, extraLength + 1);
String[] values = copyArray(strings, i, i+extraLength);
builder.putFields(header[i], ValueUtils.toValue(values));
i+=extraLength;
}
}


messageBuilder.setMessage(builder);
}
}

private int getGetExtraLength(int from, String[] headers, int valueLength) {
int count = 0;
for (int i = from + 1; i < headers.length && i < valueLength; i++) {
if (!headers[i].isEmpty()) {
break;
}
count++;
public static String [] copyArray(String [] original, int from, int to){
String [] copyArr = new String[Integer.min(to, original.length) - from];
for (int i = from; i < to && i < original.length; i++){
copyArr[i-from] = original[i];
}
return copyArr;
}

private int getHeaderArrayLength(String[] header, int index) {
int length = 1;
for (int i = index + 1; i < header.length && header[i].isEmpty(); i++) {
length++;
}
return count;
return length;
}

private void setMetadata(RawMessageMetadata originalMetadata, Message.Builder messageBuilder, String messageType, int currentIndex) {
Expand Down
50 changes: 49 additions & 1 deletion src/test/java/com/exactpro/th2/codec/csv/TestCsvCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,55 @@ void decodeArrayWithDifferentLength() throws IOException {
}

@Test
void decodeArray() throws IOException {
void decodeArrayInEnd() throws IOException {
CsvCodec codec = createCodec();
MessageGroupBatch batch = MessageGroupBatch.newBuilder()
.addGroups(MessageGroup.newBuilder()
.addMessages(createCsvMessage("A,B,C ,", "1,2,3"))
).build();
codec.handler("", batch);

var captor = ArgumentCaptor.forClass(MessageGroupBatch.class);
verify(routerMock).sendAll(captor.capture(), eq(CsvCodec.DECODE_OUT_ATTRIBUTE));

MessageGroupBatch actualBatch = captor.getValue();
assertNotNull(actualBatch, "Did not capture any publication");
assertEquals(1, actualBatch.getGroupsCount());
MessageGroup value = actualBatch.getGroups(0);
assertEquals(2, value.getMessagesCount());

Message header = getMessage(value, 0);
assertFieldCount(1, header);
Message message = getMessage(value, 1);
assertFieldCount(3, message);

assertAll(
() -> assertAll("Current message: " + header,
() -> assertEquals("Csv_Header", header.getMetadata().getMessageType()),
() -> {
assertEquals(1, header.getMetadata().getId().getSubsequenceCount());
assertEquals(1, header.getMetadata().getId().getSubsequence(0));
},
() -> assertFieldValueEquals(header, "Header", listValue("A", "B", "C", ""))
),
() -> assertAll("Current message: " + message,
() -> {
assertEquals(1, message.getMetadata().getId().getSubsequenceCount());
assertEquals(2, message.getMetadata().getId().getSubsequence(0));
},
() -> assertEquals("1", getFieldValue(message, "A", () -> "No field A. " + message)),
() -> assertEquals("2", getFieldValue(message, "B", () -> "No field B. " + message)),
() -> {
var listValues = getListValue(message, "C", () -> "No field C. " + message);
assertEquals(1, listValues.length);
assertEquals("3", listValues[0]);
}
)
);
}

@Test
void decodeArrayInMiddle() throws IOException {
CsvCodec codec = createCodec();
MessageGroupBatch batch = MessageGroupBatch.newBuilder()
.addGroups(MessageGroup.newBuilder()
Expand Down