Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into feature/create-drop-rp
  • Loading branch information
ashamanur committed Jul 7, 2017
2 parents f87797f + 7d94535 commit 82776bc
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 23 deletions.
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
## v2.7 [unreleased]
## 2.8 [unreleased]

#### Fixes

- InfluxDBResultMapper now is able to process QueryResult created when a GROUP BY clause was used [PR #345](https://github.com/influxdata/influxdb-java/pull/345)
- InfluxDB will now handle the timestamp on its own if none is provided [PR#350](https://github.com/influxdata/influxdb-java/pull/350)


## v2.7 [2017-06-26]

#### Features

- Simplify write() methods for use cases writing all points to same database and retention policy [PR #327](https://github.com/influxdata/influxdb-java/pull/327)
- QueryResult to Object mapper added [PR #341](https://github.com/influxdata/influxdb-java/pull/341)

#### Fixes

Expand All @@ -13,7 +22,7 @@
- Significant (~35%) performance improvements for write speed with less memory footprint. [PR #330](https://github.com/influxdata/influxdb-java/pull/330)
- Drop guava runtime dependency which reduces jar size from 1MB -> 49KB [PR #322](https://github.com/influxdata/influxdb-java/pull/322)

## v2.6 [2017.06-08]
## v2.6 [2017-06-08]

#### Features

Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ influxDB.query(query, 20, queryResult -> System.out.println(queryResult));
```


#### QueryResult mapper to POJO (version 2.7+ required, unreleased):
#### QueryResult mapper to POJO (version 2.7+ required):

An alternative way to handle the QueryResult object is now available.
Supposing that you have a measurement _CPU_:
Expand Down Expand Up @@ -206,13 +206,14 @@ InfluxDB influxDB = InfluxDBFactory.connect("http://localhost:8086", "root", "ro
String dbName = "myTimeseries";
QueryResult queryResult = influxDB.query(new Query("SELECT * FROM cpu", dbName));
InfluxResultMapper resultMapper = new InfluxResultMapper(); // thread-safe - can be reused
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper(); // thread-safe - can be reused
List<Cpu> cpuList = resultMapper.toPOJO(queryResult, Cpu.class);
```
**QueryResult mapper limitations**
- If your InfluxDB query contains multiple SELECT clauses, you will have to call InfluxResultMapper#toPOJO() multiple times to map every measurement returned by QueryResult to the respective POJO;
- If your InfluxDB query contains multiple SELECT clauses **for the same measurement**, InfluxResultMapper will process all results because there is no way to distinguish which one should be mapped to your POJO. It may result in an invalid collection being returned;

- A Class field annotated with _@Column(..., tag = true)_ (i.e. a [InfluxDB Tag](https://docs.influxdata.com/influxdb/v1.2/concepts/glossary/#tag-value)) must be declared as _String_.
-- _Note: With the current released version (2.7), InfluxDBResultMapper does not support QueryResult created by queries using the "GROUP BY" clause. This was fixed by [PR #345](https://github.com/influxdata/influxdb-java/pull/345)._

### Other Usages:
For additional usage examples have a look at [InfluxDBTest.java](https://github.com/influxdb/influxdb-java/blob/master/src/test/java/org/influxdb/InfluxDBTest.java "InfluxDBTest.java")
Expand All @@ -224,12 +225,12 @@ The latest version for maven dependence:
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.6</version>
<version>2.7</version>
</dependency>
```
Or when using with gradle:
```groovy
compile 'org.influxdb:influxdb-java:2.6'
compile 'org.influxdb:influxdb-java:2.7'
```
For version change history have a look at [ChangeLog](https://github.com/influxdata/influxdb-java/blob/master/CHANGELOG.md).

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<packaging>jar</packaging>
<version>2.7-SNAPSHOT</version>
<version>2.8-SNAPSHOT</version>
<name>influxdb java bindings</name>
<description>Java API to access the InfluxDB REST API</description>
<url>http://www.influxdb.org</url>
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/org/influxdb/dto/Point.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static final class Builder {
private final String measurement;
private final Map<String, String> tags = new TreeMap<>();
private Long time;
private TimeUnit precision = TimeUnit.NANOSECONDS;
private TimeUnit precision;
private final Map<String, Object> fields = new TreeMap<>();

/**
Expand Down Expand Up @@ -207,9 +207,6 @@ public Point build() {
if (this.time != null) {
point.setTime(this.time);
point.setPrecision(this.precision);
} else {
point.setTime(System.currentTimeMillis());
point.setPrecision(TimeUnit.MILLISECONDS);
}
point.setTags(this.tags);
return point;
Expand Down Expand Up @@ -292,12 +289,16 @@ public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Point [name=");
builder.append(this.measurement);
builder.append(", time=");
builder.append(this.time);
if (this.time != null) {
builder.append(", time=");
builder.append(this.time);
}
builder.append(", tags=");
builder.append(this.tags);
builder.append(", precision=");
builder.append(this.precision);
if (this.precision != null) {
builder.append(", precision=");
builder.append(this.precision);
}
builder.append(", fields=");
builder.append(this.fields);
builder.append("]");
Expand Down Expand Up @@ -368,6 +369,9 @@ private void concatenatedFields(final StringBuilder sb) {
}

private void formatedTime(final StringBuilder sb) {
if (this.time == null || this.precision == null) {
return;
}
sb.append(' ').append(TimeUnit.NANOSECONDS.convert(this.time, this.precision));
}

Expand Down
24 changes: 18 additions & 6 deletions src/main/java/org/influxdb/impl/InfluxDBResultMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -147,19 +148,32 @@ String getMeasurementName(final Class<?> clazz) {

<T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz, final List<T> result) {
int columnSize = series.getColumns().size();
ConcurrentMap<String, Field> colNameAndFieldMap = CLASS_FIELD_CACHE.get(clazz.getName());
try {
T object = null;
for (List<Object> row : series.getValues()) {
for (int i = 0; i < columnSize; i++) {
String resultColumnName = series.getColumns().get(i);
Field correspondingField = CLASS_FIELD_CACHE.get(clazz.getName()).get(resultColumnName);
Field correspondingField = colNameAndFieldMap.get(series.getColumns().get(i)/*InfluxDB columnName*/);
if (correspondingField != null) {
if (object == null) {
object = clazz.newInstance();
}
setFieldValue(object, correspondingField, row.get(i));
}
}
// When the "GROUP BY" clause is used, "tags" are returned as Map<String,String> and
// accordingly with InfluxDB documentation
// https://docs.influxdata.com/influxdb/v1.2/concepts/glossary/#tag-value
// "tag" values are always String.
if (series.getTags() != null && !series.getTags().isEmpty()) {
for (Entry<String, String> entry : series.getTags().entrySet()) {
Field correspondingField = colNameAndFieldMap.get(entry.getKey()/*InfluxDB columnName*/);
if (correspondingField != null) {
// I don't think it is possible to reach here without a valid "object"
setFieldValue(object, correspondingField, entry.getValue());
}
}
}
if (object != null) {
result.add(object);
object = null;
Expand Down Expand Up @@ -233,8 +247,7 @@ <T> boolean fieldValueModified(final Class<?> fieldType, final Field field, fina
}

<T> boolean fieldValueForPrimitivesModified(final Class<?> fieldType, final Field field, final T object,
final Object value)
throws IllegalArgumentException, IllegalAccessException {
final Object value) throws IllegalArgumentException, IllegalAccessException {
if (double.class.isAssignableFrom(fieldType)) {
field.setDouble(object, ((Double) value).doubleValue());
return true;
Expand All @@ -255,8 +268,7 @@ <T> boolean fieldValueForPrimitivesModified(final Class<?> fieldType, final Fiel
}

<T> boolean fieldValueForPrimitiveWrappersModified(final Class<?> fieldType, final Field field, final T object,
final Object value)
throws IllegalArgumentException, IllegalAccessException {
final Object value) throws IllegalArgumentException, IllegalAccessException {
if (Double.class.isAssignableFrom(fieldType)) {
field.set(object, value);
return true;
Expand Down
89 changes: 88 additions & 1 deletion src/test/java/org/influxdb/impl/InfluxDBResultMapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

Expand Down Expand Up @@ -243,7 +245,61 @@ public void testToPOJO_SeriesFromQueryResultIsNull() {
// Then...
assertTrue("there must NO entry in the result list", myList.isEmpty());
}


@Test
public void testToPOJO_QueryResultCreatedByGroupByClause() {
// Given...
mapper.cacheMeasurementClass(GroupByCarrierDeviceOS.class);

List<String> columnList = Arrays.asList("time", "median", "min", "max");

// InfluxDB client returns the time representation as Double.
Double now = Long.valueOf(System.currentTimeMillis()).doubleValue();

List<Object> firstSeriesResult = Arrays.asList(now, new Double("233.8"), new Double("0.0"),
new Double("3090744.0"));
// When the "GROUP BY" clause is used, "tags" are returned as Map<String,String>
Map<String, String> firstSeriesTagMap = new HashMap<>();
firstSeriesTagMap.put("CARRIER", "000/00");
firstSeriesTagMap.put("DEVICE_OS_VERSION", "4.4.2");

List<Object> secondSeriesResult = Arrays.asList(now, new Double("552.0"), new Double("135.0"),
new Double("267705.0"));
Map<String, String> secondSeriesTagMap = new HashMap<>();
secondSeriesTagMap.put("CARRIER", "000/01");
secondSeriesTagMap.put("DEVICE_OS_VERSION", "9.3.5");

QueryResult.Series firstSeries = new QueryResult.Series();
firstSeries.setColumns(columnList);
firstSeries.setValues(Arrays.asList(firstSeriesResult));
firstSeries.setTags(firstSeriesTagMap);
firstSeries.setName("tb_network");

QueryResult.Series secondSeries = new QueryResult.Series();
secondSeries.setColumns(columnList);
secondSeries.setValues(Arrays.asList(secondSeriesResult));
secondSeries.setTags(secondSeriesTagMap);
secondSeries.setName("tb_network");

QueryResult.Result internalResult = new QueryResult.Result();
internalResult.setSeries(Arrays.asList(firstSeries, secondSeries));

QueryResult queryResult = new QueryResult();
queryResult.setResults(Arrays.asList(internalResult));

// When...
List<GroupByCarrierDeviceOS> myList = mapper.toPOJO(queryResult, GroupByCarrierDeviceOS.class);

// Then...
GroupByCarrierDeviceOS firstGroupByEntry = myList.get(0);
assertEquals("field 'carrier' does not match", "000/00", firstGroupByEntry.carrier);
assertEquals("field 'deviceOsVersion' does not match", "4.4.2", firstGroupByEntry.deviceOsVersion);

GroupByCarrierDeviceOS secondGroupByEntry = myList.get(1);
assertEquals("field 'carrier' does not match", "000/01", secondGroupByEntry.carrier);
assertEquals("field 'deviceOsVersion' does not match", "9.3.5", secondGroupByEntry.deviceOsVersion);
}

@Measurement(name = "CustomMeasurement")
static class MyCustomMeasurement {

Expand Down Expand Up @@ -297,4 +353,35 @@ static class MyPojoWithUnsupportedField {
@Column(name = "bar")
private Date myDate;
}

/**
* Class created based on example from https://github.com/influxdata/influxdb-java/issues/343
*/
@Measurement(name = "tb_network")
static class GroupByCarrierDeviceOS {

@Column(name = "time")
private Instant time;

@Column(name = "CARRIER", tag = true)
private String carrier;

@Column(name = "DEVICE_OS_VERSION", tag = true)
private String deviceOsVersion;

@Column(name = "median")
private Double median;

@Column(name = "min")
private Double min;

@Column(name = "max")
private Double max;

@Override
public String toString() {
return "GroupByCarrierDeviceOS [time=" + time + ", carrier=" + carrier + ", deviceOsVersion=" + deviceOsVersion
+ ", median=" + median + ", min=" + min + ", max=" + max + "]";
}
}
}

0 comments on commit 82776bc

Please sign in to comment.