Skip to content

Commit e20f5b4

Browse files
authored
Merge pull request #616 from Crack/nan-skipping
Fix #614: drop NaN and infinity values from fields
2 parents 58870ae + 7e75edf commit e20f5b4

File tree

3 files changed

+71
-9
lines changed

3 files changed

+71
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
### Fixes
66

77
- Add new annotation called TimeColumn for timestamp field in POJO bean, this can set Point time and precision field correctly, also avoid UnableToParseException when flush Point to influx.
8+
- Skip fields with NaN and infinity values when writing to InfluxDB
9+
[Issue #614](https://github.com/influxdata/influxdb-java/issues/614)
810

911
## 2.15 [2019-02-22]
1012

src/main/java/org/influxdb/dto/Point.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -405,22 +405,31 @@ public String toString() {
405405
}
406406

407407
/**
408-
* calculate the lineprotocol entry for a single Point.
408+
* Calculate the lineprotocol entry for a single Point.
409+
* <p>
410+
* NaN and infinity values are silently dropped as they are unsupported:
411+
* https://github.com/influxdata/influxdb/issues/4089
409412
*
410-
* Documentation is WIP : https://github.com/influxdb/influxdb/pull/2997
413+
* @see <a href="https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/">
414+
* InfluxDB line protocol reference</a>
411415
*
412-
* https://github.com/influxdb/influxdb/blob/master/tsdb/README.md
413-
*
414-
* @return the String without newLine.
416+
* @return the String without newLine, empty when there are no fields to write
415417
*/
416418
public String lineProtocol() {
417419
return lineProtocol(null);
418420
}
419421

420422
/**
421423
* Calculate the lineprotocol entry for a single point, using a specific {@link TimeUnit} for the timestamp.
424+
* <p>
425+
* NaN and infinity values are silently dropped as they are unsupported:
426+
* https://github.com/influxdata/influxdb/issues/4089
427+
*
428+
* @see <a href="https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/">
429+
* InfluxDB line protocol reference</a>
430+
*
422431
* @param precision the time precision unit for this point
423-
* @return the String without newLine
432+
* @return the String without newLine, empty when there are no fields to write
424433
*/
425434
public String lineProtocol(final TimeUnit precision) {
426435

@@ -431,7 +440,10 @@ public String lineProtocol(final TimeUnit precision) {
431440

432441
escapeKey(sb, measurement);
433442
concatenatedTags(sb);
434-
concatenatedFields(sb);
443+
int writtenFields = concatenatedFields(sb);
444+
if (writtenFields == 0) {
445+
return "";
446+
}
435447
formatedTime(sb, precision);
436448

437449
return sb.toString();
@@ -447,10 +459,11 @@ private void concatenatedTags(final StringBuilder sb) {
447459
sb.append(' ');
448460
}
449461

450-
private void concatenatedFields(final StringBuilder sb) {
462+
private int concatenatedFields(final StringBuilder sb) {
463+
int fieldCount = 0;
451464
for (Entry<String, Object> field : this.fields.entrySet()) {
452465
Object value = field.getValue();
453-
if (value == null) {
466+
if (value == null || isNotFinite(value)) {
454467
continue;
455468
}
456469
escapeKey(sb, field.getKey());
@@ -471,13 +484,17 @@ private void concatenatedFields(final StringBuilder sb) {
471484
}
472485

473486
sb.append(',');
487+
488+
fieldCount++;
474489
}
475490

476491
// efficiently chop off the trailing comma
477492
int lengthMinusOne = sb.length() - 1;
478493
if (sb.charAt(lengthMinusOne) == ',') {
479494
sb.setLength(lengthMinusOne);
480495
}
496+
497+
return fieldCount;
481498
}
482499

483500
static void escapeKey(final StringBuilder sb, final String key) {
@@ -505,6 +522,11 @@ static void escapeField(final StringBuilder sb, final String field) {
505522
}
506523
}
507524

525+
private static boolean isNotFinite(final Object value) {
526+
return value instanceof Double && !Double.isFinite((Double) value)
527+
|| value instanceof Float && !Float.isFinite((Float) value);
528+
}
529+
508530
private void formatedTime(final StringBuilder sb, final TimeUnit precision) {
509531
if (this.time == null) {
510532
return;

src/test/java/org/influxdb/dto/PointTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,44 @@ public void testTagKeyIsSortedInLineProtocol() {
483483
assertThat(tags).isEqualTo(correctOrder);
484484
}
485485

486+
@Test
487+
public void lineProtocolSkippingOfNanFields() {
488+
String lineProtocol;
489+
490+
lineProtocol = Point
491+
.measurement("test")
492+
.time(1, TimeUnit.MILLISECONDS)
493+
.addField("float-valid", 1f)
494+
.addField("float-nan", Float.NaN)
495+
.addField("float-inf1", Float.NEGATIVE_INFINITY)
496+
.addField("float-inf2", Float.POSITIVE_INFINITY)
497+
.tag("host", "serverA")
498+
.build()
499+
.lineProtocol(TimeUnit.MILLISECONDS);
500+
assertThat(lineProtocol).isEqualTo("test,host=serverA float-valid=1.0 1");
501+
502+
lineProtocol = Point
503+
.measurement("test")
504+
.time(1, TimeUnit.MILLISECONDS)
505+
.addField("double-valid", 1d)
506+
.addField("double-nan", Double.NaN)
507+
.addField("double-inf1", Double.NEGATIVE_INFINITY)
508+
.addField("double-inf2", Double.POSITIVE_INFINITY)
509+
.tag("host", "serverA")
510+
.build()
511+
.lineProtocol(TimeUnit.MILLISECONDS);
512+
assertThat(lineProtocol).isEqualTo("test,host=serverA double-valid=1.0 1");
513+
514+
lineProtocol = Point
515+
.measurement("test")
516+
.time(1, TimeUnit.MILLISECONDS)
517+
.addField("double-nan", Double.NaN)
518+
.tag("host", "serverA")
519+
.build()
520+
.lineProtocol(TimeUnit.MILLISECONDS);
521+
assertThat(lineProtocol).isEqualTo("");
522+
}
523+
486524

487525
@Test
488526
public void testAddFieldsFromPOJONullCheck() {

0 commit comments

Comments
 (0)