org.influxdb.msgpack.MessagePackTraverser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of influxdb-java Show documentation
Show all versions of influxdb-java Show documentation
Java API to access the InfluxDB REST API
package org.influxdb.msgpack;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.influxdb.InfluxDBException;
import org.influxdb.dto.QueryResult;
import org.influxdb.dto.QueryResult.Result;
import org.influxdb.dto.QueryResult.Series;
import org.msgpack.core.ExtensionTypeHeader;
import org.msgpack.core.MessageFormat;
import org.msgpack.core.MessagePack;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.value.ValueType;
/**
* Traverse the MessagePack input stream and return Query Result object(s).
*
* @author hoan.le [at] bonitoo.io
*
*/
public class MessagePackTraverser {
private static final byte MSG_PACK_TIME_EXT_TYPE = 5;
private String lastStringNode;
/**
* Traverse over the whole message pack stream.
* This method can be used for converting query results in chunk.
*
* @param is
* The MessagePack format input stream
* @return an Iterable over the QueryResult objects
*
*/
public Iterable traverse(final InputStream is) {
MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(is);
return () -> {
return new Iterator() {
@Override
public boolean hasNext() {
try {
return unpacker.hasNext();
} catch (IOException e) {
throw new InfluxDBException(e);
}
}
@Override
public QueryResult next() {
return parse(unpacker);
}
};
};
}
/**
* Parse the message pack stream.
* This method can be used for converting query
* result from normal query response where exactly one QueryResult returned
*
* @param is
* The MessagePack format input stream
* @return QueryResult
*
*/
public QueryResult parse(final InputStream is) {
MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(is);
return parse(unpacker);
}
private QueryResult parse(final MessageUnpacker unpacker) {
QueryResult queryResult = new QueryResult();
QueryResultModelPath queryResultPath = new QueryResultModelPath();
queryResultPath.add("queryResult", queryResult);
try {
traverse(unpacker, queryResultPath, 1);
} catch (IOException e) {
throw new InfluxDBException(e);
}
return queryResult;
}
void traverse(final MessageUnpacker unpacker, final QueryResultModelPath queryResultPath, final int readAmount)
throws IOException {
int amount = 0;
while (unpacker.hasNext() && amount < readAmount) {
MessageFormat format = unpacker.getNextFormat();
ValueType type = format.getValueType();
int length;
ExtensionTypeHeader extension;
Object o = null;
byte[] dst;
String addedName = null;
Object addedObject = null;
switch (type) {
case NIL:
unpacker.unpackNil();
break;
case BOOLEAN:
o = unpacker.unpackBoolean();
break;
case INTEGER:
switch (format) {
case UINT64:
o = unpacker.unpackBigInteger();
break;
case INT64:
case UINT32:
o = unpacker.unpackLong();
break;
default:
o = unpacker.unpackInt();
break;
}
break;
case FLOAT:
o = unpacker.unpackDouble();
break;
case STRING:
o = unpacker.unpackString();
lastStringNode = (String) o;
if ("name".equals(o) && queryResultPath.compareEndingPath("series")) {
queryResultPath.add("name", null);
} else if (queryResultPath.compareEndingPath("name")) {
queryResultPath.removeLast();
Series series = queryResultPath.getLastObject();
series.setName((String) o);
} else if (queryResultPath.compareEndingPath("tags")) {
queryResultPath.add("tagKey", o);
} else if (queryResultPath.compareEndingPath("tagKey")) {
String tagKey = queryResultPath.getLastObject();
queryResultPath.removeLast();
Map tags = queryResultPath.getLastObject();
tags.put(tagKey, (String) o);
} else if (queryResultPath.compareEndingPath("columns")) {
List columns = queryResultPath.getLastObject();
columns.add((String) o);
}
break;
case BINARY:
length = unpacker.unpackBinaryHeader();
dst = new byte[length];
unpacker.readPayload(dst);
break;
case ARRAY:
length = unpacker.unpackArrayHeader();
if (length > 0) {
if ("results".equals(lastStringNode)) {
QueryResult queryResult = queryResultPath.getLastObject();
List results = new ArrayList<>();
queryResult.setResults(results);
addedName = "results";
addedObject = results;
} else if ("series".equals(lastStringNode) && queryResultPath.compareEndingPath("result")) {
Result result = queryResultPath.getLastObject();
List series = new ArrayList<>();
result.setSeries(series);
addedName = "seriesList";
addedObject = series;
} else if ("columns".equals(lastStringNode) && queryResultPath.compareEndingPath("series")) {
Series series = queryResultPath.getLastObject();
List columns = new ArrayList<>();
series.setColumns(columns);
addedName = "columns";
addedObject = columns;
} else if ("values".equals(lastStringNode) && queryResultPath.compareEndingPath("series")) {
Series series = queryResultPath.getLastObject();
List> values = new ArrayList<>();
series.setValues(values);
addedName = "values";
addedObject = values;
} else if (queryResultPath.compareEndingPath("values")) {
List> values = queryResultPath.getLastObject();
List