diff --git a/Readme.md b/Readme.md
index 2c5a90e..8dfdef3 100644
--- a/Readme.md
+++ b/Readme.md
@@ -20,6 +20,26 @@ Following files define and describe application properties:
It is possible to overwrite properties by defining new values in `${HOME}/.config/daq/queryrest.properties`
+## Maven
+
+Upload jar to the Maven repository (from ch.psi.daq.buildall):
+
+```bash
+./gradlew ch.psi.daq.queryrest:uploadArchives
+```
+
+## DropIt
+
+Upload jar DropIt (from ch.psi.daq.buildall):
+
+```bash
+./gradlew ch.psi.daq.queryrest:dropIt -x test
+```
+
+## Local Instance
+
+[DAQLocal](https://github.psi.ch/projects/ST/repos/ch.psi.daq.daqlocal/browse) provides a local instance of the DAQ system for testing purposes (allowing users/developers to verify their code before they come to PSI to do their research and interact with the DAQ cluster).
+
# REST Interface
diff --git a/build.gradle b/build.gradle
index c46ec1f..bc33bf7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,10 +18,6 @@ applicationDefaultJvmArgs = [
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006"
]
-//configurations {
-// compile.exclude group: "com.fasterxml.jackson.core"
-//}
-
dependencies {
compile (project(':ch.psi.daq.query'))
compile 'org.hibernate:hibernate-validator:5.2.0.Final'
@@ -42,6 +38,6 @@ uploadArchives {
}
}
-task dropItQueryREST(dependsOn: build) << {
+task dropIt(dependsOn: build) << {
exec{ executable "curl"; args "-X", "POST", "-F", "file=@build/libs/ch.psi.daq.queryrest-" + version + ".jar", "http://dropit.psi.ch:8080/upload"; }
}
\ No newline at end of file
diff --git a/src/main/java/ch/psi/daq/queryrest/config/QueryRestConfig.java b/src/main/java/ch/psi/daq/queryrest/config/QueryRestConfig.java
index 3ef9163..eebc710 100644
--- a/src/main/java/ch/psi/daq/queryrest/config/QueryRestConfig.java
+++ b/src/main/java/ch/psi/daq/queryrest/config/QueryRestConfig.java
@@ -7,6 +7,7 @@ import java.util.List;
import java.util.Set;
import java.util.function.Function;
+import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.slf4j.Logger;
@@ -70,6 +71,39 @@ public class QueryRestConfig extends WebMvcConfigurerAdapter {
@Resource
private Environment env;
+
+ @Resource
+ private ObjectMapper objectMapper;
+
+ @PostConstruct
+ public void afterPropertiesSet() {
+ // add deserializers to ObjectMapper
+ String packageName = AbstractQuery.class.getPackage().getName();
+ Class abstractQueryClass = AbstractQuery.class;
+ AttributeBasedDeserializer abstractQueryDeserializer =
+ new AttributeBasedDeserializer(abstractQueryClass).register(packageName);
+ SimpleModule module = new SimpleModule("PolymorphicAbstractQuery", Version.unknownVersion());
+ module.addDeserializer(abstractQueryClass, abstractQueryDeserializer);
+ objectMapper.registerModule(module);
+
+ // only include non-null values
+ objectMapper.setSerializationInclusion(Include.NON_NULL);
+ // Mixin which is used dynamically to filter out which properties get serialised and which
+ // won't. This way, the user can specify which columns are to be received.
+ objectMapper.addMixIn(DataEvent.class, PropertyFilterMixin.class);
+ objectMapper.addMixIn(StorelessStatistics.class, PropertyFilterMixin.class);
+ objectMapper.addMixIn(EnumMap.class, PropertyFilterMixin.class);
+
+ // defines how to writer inner Streams (i.e. Stream>> toSerialize)
+ module = new SimpleModule("Streams API", Version.unknownVersion());
+ module.addSerializer(new JsonStreamSerializer());
+ objectMapper.registerModule(module);
+
+ // by default, byte[] are written as String
+ module = new SimpleModule("byte[]", Version.unknownVersion());
+ module.addSerializer(new JsonByteArraySerializer());
+ objectMapper.registerModule(module);
+ }
/**
* {@inheritDoc}
@@ -81,44 +115,11 @@ public class QueryRestConfig extends WebMvcConfigurerAdapter {
* This is necessary so that the message conversion uses the configured object mapper.
* Otherwise, a separate object mapper is instantiated for Springs message conversion.
*/
- converter.setObjectMapper(objectMapper());
+ converter.setObjectMapper(objectMapper);
converters.add(converter);
super.configureMessageConverters(converters);
}
- @Bean
- public ObjectMapper objectMapper() {
- ObjectMapper mapper = new ObjectMapper();
-
- String packageName = AbstractQuery.class.getPackage().getName();
- Class abstractQueryClass = AbstractQuery.class;
- AttributeBasedDeserializer abstractQueryDeserializer =
- new AttributeBasedDeserializer(abstractQueryClass).register(packageName);
- SimpleModule module = new SimpleModule("PolymorphicAbstractQuery", Version.unknownVersion());
- module.addDeserializer(abstractQueryClass, abstractQueryDeserializer);
- mapper.registerModule(module);
-
- // only include non-null values
- mapper.setSerializationInclusion(Include.NON_NULL);
- // Mixin which is used dynamically to filter out which properties get serialised and which
- // won't. This way, the user can specify which columns are to be received.
- mapper.addMixIn(DataEvent.class, PropertyFilterMixin.class);
- mapper.addMixIn(StorelessStatistics.class, PropertyFilterMixin.class);
- mapper.addMixIn(EnumMap.class, PropertyFilterMixin.class);
-
- // defines how to writer inner Streams (i.e. Stream>> toSerialize)
- module = new SimpleModule("Streams API", Version.unknownVersion());
- module.addSerializer(new JsonStreamSerializer());
- mapper.registerModule(module);
-
- // by default, byte[] are written as String
- module = new SimpleModule("byte[]", Version.unknownVersion());
- module.addSerializer(new JsonByteArraySerializer());
- mapper.registerModule(module);
-
- return mapper;
- }
-
@Bean
public JsonFactory jsonFactory() {
return new JsonFactory();
diff --git a/src/main/java/ch/psi/daq/queryrest/controller/QueryRestController.java b/src/main/java/ch/psi/daq/queryrest/controller/QueryRestController.java
index d4d2256..25666df 100644
--- a/src/main/java/ch/psi/daq/queryrest/controller/QueryRestController.java
+++ b/src/main/java/ch/psi/daq/queryrest/controller/QueryRestController.java
@@ -107,6 +107,15 @@ public class QueryRestController {
try {
LOGGER.debug("Executing query '{}'", query.getClass().getSimpleName());
+ // write the response back to the client using java 8 streams
+ responseStreamWriter.respond(executeQuery(query), query, res);
+ } catch (Throwable t) {
+ LOGGER.error("Failed execute query '{}'.", query, t);
+ throw t;
+ }
+ }
+
+ public Stream> executeQuery(AbstractQuery query) {
QueryAnalyzer queryAnalizer = queryAnalizerFactory.apply(query);
// all the magic happens here
@@ -115,13 +124,8 @@ public class QueryRestController {
// do post-process
Stream> channelToData = queryAnalizer.postProcess(channelToDataEvents);
-
- // write the response back to the client using java 8 streams
- responseStreamWriter.respond(channelToData, query, res);
- } catch (Throwable t) {
- LOGGER.error("Failed execute query '{}'.", query, t);
- throw t;
- }
+
+ return channelToData;
}
private QueryProcessor getQueryProcessor(DBMode dbMode) {
diff --git a/src/main/resources/queryrest.properties b/src/main/resources/queryrest.properties
index 192ccb3..55b2cd3 100644
--- a/src/main/resources/queryrest.properties
+++ b/src/main/resources/queryrest.properties
@@ -1,6 +1,3 @@
-# port for the Spring boot application's embedded Tomcat server
-server.port=8080
-
# defines the fields that are included in the response
# if no fields have been specified by the user
queryrest.default.response.fields=channel,pulseId,globalMillis,globalNanos,iocMillis,iocNanos,shape,value