From 1c1ddf773ae355eb27444881556eb70293c397e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=A4rki?= Date: Tue, 13 Oct 2015 13:18:04 +0200 Subject: [PATCH] ATEST-242 --- Readme.md | 20 ++++++ build.gradle | 6 +- .../daq/queryrest/config/QueryRestConfig.java | 69 ++++++++++--------- .../controller/QueryRestController.java | 18 +++-- src/main/resources/queryrest.properties | 3 - 5 files changed, 67 insertions(+), 49 deletions(-) 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