Repository: influxdata/influxdb-java (java)

Issue:
Lack of Point.Builder#addField(String, int) causes unexpected result
I have a data class that looks kind of like this:

```java
@Measurement(name = "myMeasurement")
public class MyMeasurement {

    @Column(name = "myField")
    private int myField;

    // ... accessors, constructors, etc
}
```

In my application, I'm constructing points like this:

```java
Point point = Point.measurementByPOJO(MyMeasurement.class)
        .addFieldsFromPOJO(someMeasurement)
        .build();
```

In my unit tests, I'm trying to verify that my InfluxDB client is called with the right parameters:

```java
@Test
public void myMethod_callsInfluxWithCorrectPoint() {
    // ... setup and calling my method
    int value = 15;
    Point expected = Point.measurement("myMeasurement")
            .addField("myField", 15)
            .build();
    verify(mockInfluxDb).write(expected);
}
```

This test fails saying that the expected arguments don't match the actual arguments, but the serialization of the `Point`s look identical. What's going on is that my `int` parameter is being coerced to match the `addField(String, long)` overload, so the field is being stored as `Long`, and then `verify()` fails because of the type mismatch.

Ultimately, I worked around this by declaring `value` as `Integer` so that the `addField(String, Number)` overload was used. But I spent a lot of time spinning my wheels trying to understand why the test was failing.

### What to do

* Should there be an `addField(String, int)` (and other primitive numeric types)?
* Should users just stick to `long` or `double` for all numeric fields?

Pull request:
fix: consistency between addField from POJO and regular addField
Closes #653 

This PR fix inconsistency between coercing primitive numeric types by https://github.com/influxdata/influxdb-java/blob/37b93e9f5d20461142b186ceac4e4aa89503550c/src/main/java/org/influxdb/dto/Point.java#L235

and by https://github.com/influxdata/influxdb-java/blob/37b93e9f5d20461142b186ceac4e4aa89503550c/src/main/java/org/influxdb/dto/Point.java#L181.

The previous version of `public Builder addField(..., ...)` coerce `int` and `short` to `long` and `float` to `double`.

Patch:
diff --git a/src/main/java/org/influxdb/dto/Point.java b/src/main/java/org/influxdb/dto/Point.java
index 478995a..5ba4d52 100644
--- a/src/main/java/org/influxdb/dto/Point.java
+++ b/src/main/java/org/influxdb/dto/Point.java
@@ -178,6 +178,21 @@ public class Point {
       return this;
     }
 
+    public Builder addField(final String field, final int value) {
+      fields.put(field, value);
+      return this;
+    }
+
+    public Builder addField(final String field, final float value) {
+      fields.put(field, value);
+      return this;
+    }
+
+    public Builder addField(final String field, final short value) {
+      fields.put(field, value);
+      return this;
+    }
+
     public Builder addField(final String field, final Number value) {
       fields.put(field, value);
       return this;


Test patch:
diff --git a/src/test/java/org/influxdb/dto/PointTest.java b/src/test/java/org/influxdb/dto/PointTest.java
index f2003b1..f21e7f4 100644
--- a/src/test/java/org/influxdb/dto/PointTest.java
+++ b/src/test/java/org/influxdb/dto/PointTest.java
@@ -1,6 +1,7 @@
 package org.influxdb.dto;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
 
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
@@ -15,14 +16,17 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.influxdb.BuilderException;
+import org.influxdb.InfluxDB;
 import org.influxdb.annotation.Column;
 import org.influxdb.annotation.Measurement;
 import org.influxdb.annotation.TimeColumn;
+import org.influxdb.impl.InfluxDBImpl;
 import org.junit.Assert;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.platform.runner.JUnitPlatform;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /**
  * Test for the Point DTO.
@@ -615,6 +619,32 @@ public class PointTest {
         Assertions.assertEquals(pojo.uuid, p.getTags().get("uuid"));
     }
 
+    @Test
+    public void testAddFieldsFromPOJOConsistentWithAddField() {
+        PojoNumberPrimitiveTypes pojo = new PojoNumberPrimitiveTypes();
+        pojo.shortType = 128;
+        pojo.intType = 1_048_576;
+        pojo.longType = 1_073_741_824;
+        pojo.floatType = 246.8f;
+        pojo.doubleType = 123.4;
+
+        Point pojo_point = Point.measurementByPOJO(pojo.getClass()).addFieldsFromPOJO(pojo).build();
+
+        InfluxDB mockInfluxDB = mock(InfluxDBImpl.class);
+        mockInfluxDB.write(pojo_point);
+
+        Point expected = Point.measurement("PojoNumberPrimitiveTypes")
+                .addField("shortType", pojo.shortType)
+                .addField("intType", pojo.intType)
+                .addField("longType", pojo.longType)
+                .addField("floatType", pojo.floatType)
+                .addField("doubleType", pojo.doubleType)
+                .build();
+
+        Assert.assertEquals(pojo_point.lineProtocol(), expected.lineProtocol());
+        Mockito.verify(mockInfluxDB).write(expected);
+    }
+
     @Test
     public void testAddFieldsFromPOJOWithPublicAttributes() {
 
@@ -858,4 +888,23 @@ public class PointTest {
         @Column(name = "subClassField")
         String subValue;
     }
+
+    @Measurement(name = "PojoNumberPrimitiveTypes")
+    static class PojoNumberPrimitiveTypes
+    {
+        @Column(name = "shortType")
+        public short shortType;
+
+        @Column(name = "intType")
+        public int intType;
+
+        @Column(name = "longType")
+        public long longType;
+
+        @Column(name = "floatType")
+        public float floatType;
+
+        @Column(name = "doubleType")
+        public double doubleType;
+    }
 }