Skip to content

Commit a018d59

Browse files
authored
fix: add a floating point check (#76)
1 parent c008f81 commit a018d59

File tree

6 files changed

+42
-21
lines changed

6 files changed

+42
-21
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ plugins {
2222
}
2323

2424
group 'io.odpf'
25-
version '0.3.6'
25+
version '0.3.7'
2626

2727
repositories {
2828
mavenCentral()

src/main/java/io/odpf/depot/bigquery/converter/MessageRecordConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public Records convert(List<OdpfMessage> messages) {
4444
} catch (EmptyMessageException | UnsupportedOperationException e) {
4545
ErrorInfo errorInfo = new ErrorInfo(e, ErrorType.INVALID_MESSAGE_ERROR);
4646
invalidRecords.add(new Record(message.getMetadata(), Collections.emptyMap(), index, errorInfo));
47-
} catch (DeserializerException e) {
47+
} catch (DeserializerException | IllegalArgumentException e) {
4848
ErrorInfo errorInfo = new ErrorInfo(e, ErrorType.DESERIALIZATION_ERROR);
4949
invalidRecords.add(new Record(message.getMetadata(), Collections.emptyMap(), index, errorInfo));
5050
}

src/main/java/io/odpf/depot/message/proto/ProtoOdpfParsedMessage.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.odpf.depot.message.proto;
22

33
import com.google.api.client.util.DateTime;
4+
import com.google.api.client.util.Preconditions;
45
import com.google.protobuf.Descriptors;
56
import com.google.protobuf.DynamicMessage;
67
import io.odpf.depot.common.Tuple;
@@ -89,13 +90,24 @@ private Map<String, Object> getMappings(DynamicMessage message, Properties colum
8990
Tuple<String, Object> nestedColumns = getNestedColumnName(field, value);
9091
row.put(nestedColumns.getFirst(), nestedColumns.getSecond());
9192
} else {
93+
floatCheck(fieldValue);
9294
row.put(columnName, fieldValue);
9395
}
9496
}
9597
});
9698
return row;
9799
}
98100

101+
private void floatCheck(Object fieldValue) {
102+
if (fieldValue instanceof Float) {
103+
float floatValue = ((Number) fieldValue).floatValue();
104+
Preconditions.checkArgument(!Float.isInfinite(floatValue) && !Float.isNaN(floatValue));
105+
} else if (fieldValue instanceof Double) {
106+
double doubleValue = ((Number) fieldValue).doubleValue();
107+
Preconditions.checkArgument(!Double.isInfinite(doubleValue) && !Double.isNaN(doubleValue));
108+
}
109+
}
110+
99111
private Tuple<String, Object> getNestedColumnName(Object field, Object value) {
100112
try {
101113
String columnName = getNestedColumnName((Properties) value);
@@ -127,6 +139,7 @@ private void addRepeatedFields(Map<String, Object> row, Object value, List<Objec
127139
if (f instanceof Instant) {
128140
repeatedNestedFields.add(new DateTime(((Instant) f).toEpochMilli()));
129141
} else {
142+
floatCheck(f);
130143
repeatedNestedFields.add(f);
131144
}
132145
assert value instanceof String;

src/test/java/io/odpf/depot/message/proto/ProtoOdpfParsedMessageTest.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,22 @@
11
package io.odpf.depot.message.proto;
22

33
import com.google.api.client.util.DateTime;
4-
import com.google.protobuf.Descriptors;
5-
import com.google.protobuf.Duration;
6-
import com.google.protobuf.DynamicMessage;
7-
import com.google.protobuf.ListValue;
8-
import com.google.protobuf.Message;
9-
import com.google.protobuf.Struct;
10-
import com.google.protobuf.Timestamp;
11-
import com.google.protobuf.Value;
4+
import com.google.protobuf.*;
125
import com.google.protobuf.util.JsonFormat;
13-
import io.odpf.depot.StatusBQ;
14-
import io.odpf.depot.TestBookingLogMessage;
15-
import io.odpf.depot.TestKeyBQ;
16-
import io.odpf.depot.TestLocation;
17-
import io.odpf.depot.TestMessage;
18-
import io.odpf.depot.TestMessageBQ;
19-
import io.odpf.depot.TestNestedMessageBQ;
20-
import io.odpf.depot.TestNestedRepeatedMessageBQ;
21-
import io.odpf.depot.TestTypesMessage;
6+
import io.odpf.depot.*;
227
import io.odpf.depot.message.OdpfMessageSchema;
238
import io.odpf.depot.message.ParsedOdpfMessage;
249
import io.odpf.depot.message.proto.converter.fields.MessageProtoField;
2510
import io.odpf.depot.message.proto.converter.fields.ProtoField;
2611
import io.odpf.stencil.Parser;
2712
import io.odpf.stencil.StencilClientFactory;
2813
import io.odpf.stencil.client.StencilClient;
14+
import org.apache.xerces.impl.dv.util.Base64;
2915
import org.json.JSONArray;
3016
import org.junit.Assert;
3117
import org.junit.Before;
3218
import org.junit.Test;
19+
import org.junit.jupiter.api.Assertions;
3320
import org.mockito.Mock;
3421
import org.mockito.Mockito;
3522

@@ -45,7 +32,7 @@
4532

4633
public class ProtoOdpfParsedMessageTest {
4734

48-
private static JsonFormat.Printer printer = JsonFormat.printer()
35+
private static final JsonFormat.Printer PRINTER = JsonFormat.printer()
4936
.preservingProtoFieldNames()
5037
.omittingInsignificantWhitespace();
5138
private Timestamp createdAt;
@@ -85,6 +72,8 @@ public void setUp() throws IOException, Descriptors.DescriptorValidationExceptio
8572
put(String.format("%s", TestBookingLogMessage.TopicMetadata.class.getName()), TestBookingLogMessage.TopicMetadata.getDescriptor());
8673
put(String.format("%s", TestTypesMessage.class.getName()), TestTypesMessage.getDescriptor());
8774
put(String.format("%s", TestMessage.class.getName()), TestMessage.getDescriptor());
75+
put(String.format("%s", FloatTest.class.getName()), FloatTest.getDescriptor());
76+
put(String.format("%s", FloatTestContainer.class.getName()), FloatTestContainer.getDescriptor());
8877
put("io.odpf.depot.TestMessageBQ.CurrentStateEntry", TestMessageBQ.getDescriptor().getNestedTypes().get(0));
8978
put("com.google.protobuf.Struct.FieldsEntry", Struct.getDescriptor().getNestedTypes().get(0));
9079
put("com.google.protobuf.Duration", com.google.protobuf.Duration.getDescriptor());
@@ -109,6 +98,15 @@ public void shouldReturnFieldsInProperties() throws IOException {
10998
assertEquals(21, dateFields.get("day"));
11099
}
111100

101+
@Test
102+
public void shouldThrowExceptionWhenFloatingPointIsNaN() throws IOException {
103+
String data = "ogQFJQAAwH8=";
104+
byte[] decode = Base64.decode(data);
105+
DynamicMessage message = DynamicMessage.parseFrom(FloatTest.getDescriptor(), decode);
106+
OdpfMessageSchema odpfMessageSchema = odpfMessageParser.getSchema("io.odpf.depot.FloatTest", descriptorsMap);
107+
Assertions.assertThrows(IllegalArgumentException.class, () -> new ProtoOdpfParsedMessage(message).getMapping(odpfMessageSchema));
108+
}
109+
112110
@Test
113111
public void shouldParseDurationMessageSuccessfully() throws IOException {
114112
TestMessageBQ message = TestProtoUtil.generateTestMessage(now);
@@ -425,7 +423,7 @@ public void shouldGetRepeatableStructField() throws IOException {
425423
JSONArray expectedArray = new JSONArray();
426424
JSONArray actualArray = new JSONArray();
427425
for (int ii = 0; ii < message.getAttributesCount(); ii++) {
428-
expectedArray.put(printer.print(message.getAttributes(ii)));
426+
expectedArray.put(PRINTER.print(message.getAttributes(ii)));
429427
actualArray.put(attributes.get(ii));
430428
}
431429
Assert.assertEquals(expectedArray.toString(), actualArray.toString());

src/test/java/io/odpf/depot/message/proto/TestProtoUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class TestProtoUtil {
1515
public static final int TRIP_DURATION_NANOS = 1000;
1616
private static final long TRIP_DURATION_SECONDS_1 = 12;
1717
private static final long TRIP_DURATION_SECONDS_2 = 15;
18+
private static final float PRICE = 12.12f;
1819
private static int call = 0;
1920

2021
public static TestMessageBQ generateTestMessage(Instant now) {
@@ -25,6 +26,7 @@ public static TestMessageBQ generateTestMessage(Instant now) {
2526
.setOrderUrl("order-url-" + call)
2627
.setOrderDetails("order-details-" + call)
2728
.setCreatedAt(createdAt)
29+
.setPrice(PRICE)
2830
.setStatus(StatusBQ.COMPLETED)
2931
.setTripDuration(Duration.newBuilder().setSeconds(1).setNanos(TRIP_DURATION_NANOS).build())
3032
.addUpdatedAt(createdAt)

src/test/proto/TestMessage.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ message TestKey {
1616
string order_url = 2;
1717
}
1818

19+
message FloatTest {
20+
FloatTestContainer container = 68;
21+
}
22+
23+
message FloatTestContainer {
24+
float value = 4;
25+
}
26+
1927
message TestMessage {
2028
string order_number = 1;
2129
string order_url = 2;

0 commit comments

Comments
 (0)