Async read, query REST etc.

This commit is contained in:
Fabian Märki
2015-07-24 15:34:35 +02:00
parent 9b370cebe3
commit 689622be07
10 changed files with 282 additions and 221 deletions
@@ -2,14 +2,16 @@ package ch.psi.daq.queryrest.response;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.ServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
@@ -22,6 +24,7 @@ import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import ch.psi.daq.domain.cassandra.DataEvent;
import ch.psi.daq.query.model.AbstractQuery;
import ch.psi.daq.query.model.AggregationEnum;
import ch.psi.daq.query.model.QueryField;
/**
* Takes a Java 8 stream and writes it to the output stream provided by the {@link ServletResponse}
@@ -31,15 +34,12 @@ public class ResponseStreamWriter {
private static final Logger logger = LoggerFactory.getLogger(ResponseStreamWriter.class);
@Autowired
@Resource
private JsonFactory jsonFactory;
@Autowired
@Resource
private ObjectMapper mapper;
@Autowired
private Set<String> defaultResponseFields;
/**
* Responding with the the contents of the stream by writing into the output stream of the
* {@link ServletResponse}.
@@ -49,16 +49,26 @@ public class ResponseStreamWriter {
* @param response {@link ServletResponse} instance given by the current HTTP request
* @throws IOException thrown if writing to the output stream fails
*/
public void respond(Stream<DataEvent> stream, AbstractQuery query, ServletResponse response) throws IOException {
public void respond(Stream<Entry<String, Stream<? extends DataEvent>>> stream, AbstractQuery query,
ServletResponse response) throws IOException {
Set<String> includedFields = query.getFieldsOrDefault(defaultResponseFields);
Set<QueryField> queryFields = query.getFields();
List<AggregationEnum> aggregations = query.getAggregations();
if (query.getAggregations() != null) {
includedFields = new LinkedHashSet<String>(includedFields);
Set<String> includedFields =
new LinkedHashSet<String>(queryFields.size() + (aggregations != null ? aggregations.size() : 0));
for (QueryField field : queryFields) {
includedFields.add(field.name());
}
if (aggregations != null) {
for (AggregationEnum aggregation : query.getAggregations()) {
includedFields.add(aggregation.name());
}
}
// do not write channel since it is already provided as key in mapping
includedFields.remove(QueryField.channel.name());
ObjectWriter writer = configureWriter(includedFields);
respondInternal(stream, response, writer);
}
@@ -87,20 +97,39 @@ public class ResponseStreamWriter {
* @param writer configured writer that includes the fields the end user wants to see
* @throws IOException thrown if writing to the output stream fails
*/
private void respondInternal(Stream<DataEvent> stream, ServletResponse response, ObjectWriter writer)
private void respondInternal(Stream<Entry<String, Stream<? extends DataEvent>>> stream, ServletResponse response,
ObjectWriter writer)
throws IOException {
JsonGenerator generator = jsonFactory.createGenerator(response.getOutputStream(), JsonEncoding.UTF8);
generator.writeStartArray();
stream.forEach(ds -> {
try {
logger.trace("Writing value for: {}", ds);
// use the writer created just before
writer.writeValue(generator, ds);
} catch (Exception e) {
logger.error("", e);
}
});
stream
/* ensure elements are sequentially written to the stream */
.sequential()
.forEach(
entry -> {
try {
generator.writeStartObject();
generator.writeStringField(QueryField.channel.name(), entry.getKey());
generator.writeArrayFieldStart("values");
entry.getValue()
/* ensure elements are sequentially written to the stream */
.sequential()
.forEach(
dataEvent -> {
try {
writer.writeValue(generator, dataEvent);
} catch (Exception e) {
logger.error("Could not write event with pulse-id '{}' of channel '{}'",
dataEvent.getPulseId(), entry.getKey(), e);
}
});
generator.writeEndArray();
generator.writeEndObject();
} catch (Exception e) {
logger.error("Could not write channel name of channel '{}'", entry.getKey(), e);
}
});
generator.writeEndArray();
generator.flush();
generator.close();