ATEST-124:
- implement the query validator
This commit is contained in:
@ -24,7 +24,11 @@ applicationDefaultJvmArgs = [
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile (project(':ch.psi.daq.query'))
|
compile (project(':ch.psi.daq.query'))
|
||||||
compile libraries.spring_boot_starter_web
|
compile 'org.hibernate:hibernate-validator:5.2.0.Final'
|
||||||
|
|
||||||
|
compile(libraries.spring_boot_starter_web) {
|
||||||
|
exclude group: 'org.slf4j', module: 'log4j-over-slf4j'
|
||||||
|
}
|
||||||
compile libraries.commons_lang
|
compile libraries.commons_lang
|
||||||
|
|
||||||
testCompile libraries.spring_boot_starter_test
|
testCompile libraries.spring_boot_starter_test
|
||||||
@ -39,5 +43,5 @@ uploadArchives {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task dropItQueryREST(dependsOn: build) << {
|
task dropItQueryREST(dependsOn: build) << {
|
||||||
exec{ executable "curl"; args "-X", "POST", "-F", "file=@build/libs/ch.psi.daq.queryrest-" + version + ".jar", "http://dropit.psi.ch:8080"; }
|
exec{ executable "curl"; args "-X", "POST", "-F", "file=@build/libs/ch.psi.daq.queryrest-" + version + ".jar", "http://dropit.psi.ch:8080/upload"; }
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ import org.springframework.context.annotation.Import;
|
|||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
@ -33,6 +34,7 @@ import ch.psi.daq.query.model.AbstractQuery;
|
|||||||
import ch.psi.daq.query.model.Aggregation;
|
import ch.psi.daq.query.model.Aggregation;
|
||||||
import ch.psi.daq.query.model.Query;
|
import ch.psi.daq.query.model.Query;
|
||||||
import ch.psi.daq.query.model.QueryField;
|
import ch.psi.daq.query.model.QueryField;
|
||||||
|
import ch.psi.daq.queryrest.controller.QueryValidator;
|
||||||
import ch.psi.daq.queryrest.model.PropertyFilterMixin;
|
import ch.psi.daq.queryrest.model.PropertyFilterMixin;
|
||||||
import ch.psi.daq.queryrest.response.JsonStreamSerializer;
|
import ch.psi.daq.queryrest.response.JsonStreamSerializer;
|
||||||
import ch.psi.daq.queryrest.response.ResponseStreamWriter;
|
import ch.psi.daq.queryrest.response.ResponseStreamWriter;
|
||||||
@ -141,6 +143,11 @@ public class QueryRestConfig {
|
|||||||
return defaultResponseAggregations;
|
return defaultResponseAggregations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Validator queryValidator() {
|
||||||
|
return new QueryValidator();
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================================
|
// ==========================================================================================
|
||||||
// TODO: This is simply for initial / rudimentary testing - remove once further evolved
|
// TODO: This is simply for initial / rudimentary testing - remove once further evolved
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -2,8 +2,6 @@ package ch.psi.daq.queryrest.controller;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -11,6 +9,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -86,16 +85,16 @@ public class QueryRestController {
|
|||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
value = QUERY,
|
value = QUERY,
|
||||||
method = RequestMethod.POST,
|
method = RequestMethod.POST,
|
||||||
consumes = {MediaType.APPLICATION_JSON_VALUE},
|
consumes = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
produces = {MediaType.APPLICATION_JSON_VALUE})
|
// , produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
public void executeQuery(@RequestBody AbstractQuery query, HttpServletResponse res) throws IOException {
|
public void executeQuery(@RequestBody @Valid AbstractQuery query, HttpServletResponse res) throws IOException {
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Execute query '{}'", query.getClass().getSimpleName());
|
LOGGER.debug("Execute query '{}'", query.getClass().getSimpleName());
|
||||||
|
|
||||||
QueryAnalyzer queryAnalizer = queryAnalizerFactory.apply(query);
|
QueryAnalyzer queryAnalizer = queryAnalizerFactory.apply(query);
|
||||||
queryAnalizer.validate();
|
queryAnalizer.validate();
|
||||||
|
|
||||||
extendQuery(query);
|
// extendQuery(query);
|
||||||
|
|
||||||
// all the magic happens here
|
// all the magic happens here
|
||||||
Stream<Entry<String, Stream<? extends DataEvent>>> channelToDataEvents = queryProcessor.process(queryAnalizer);
|
Stream<Entry<String, Stream<? extends DataEvent>>> channelToDataEvents = queryProcessor.process(queryAnalizer);
|
||||||
@ -111,14 +110,14 @@ public class QueryRestController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extendQuery(AbstractQuery query) {
|
// private void extendQuery(AbstractQuery query) {
|
||||||
if (query.getFields() == null || query.getFields().isEmpty()) {
|
// if (query.getFields() == null || query.getFields().isEmpty()) {
|
||||||
query.setFields(new LinkedHashSet<>(defaultResponseFields));
|
// query.setFields(new LinkedHashSet<>(defaultResponseFields));
|
||||||
}
|
// }
|
||||||
if(query.getAggregations() == null || query.getAggregations().isEmpty()){
|
// if(query.getAggregations() == null || query.getAggregations().isEmpty()){
|
||||||
query.setAggregations(new LinkedList<>(defaultResponseAggregations));
|
// query.setAggregations(new LinkedList<>(defaultResponseAggregations));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// ==========================================================================================
|
// ==========================================================================================
|
||||||
// TODO: This is simply for initial / rudimentary testing - remove once further evolved
|
// TODO: This is simply for initial / rudimentary testing - remove once further evolved
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package ch.psi.daq.queryrest.controller;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.springframework.validation.Errors;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
|
||||||
|
import ch.psi.daq.query.model.AbstractQuery;
|
||||||
|
import ch.psi.daq.query.model.Aggregation;
|
||||||
|
import ch.psi.daq.query.model.QueryField;
|
||||||
|
import ch.psi.daq.queryrest.config.QueryRestConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zellweger_c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QueryValidator implements Validator {
|
||||||
|
|
||||||
|
@Resource(name = QueryRestConfig.BEAN_NAME_DEFAULT_RESPONSE_FIELDS)
|
||||||
|
private Set<QueryField> defaultResponseFields;
|
||||||
|
|
||||||
|
@Resource(name = QueryRestConfig.BEAN_NAME_DEFAULT_RESPONSE_AGGREGATIONS)
|
||||||
|
private Set<Aggregation> defaultResponseAggregations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> clazz) {
|
||||||
|
return AbstractQuery.class.isAssignableFrom(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void validate(Object target, Errors errors) {
|
||||||
|
|
||||||
|
AbstractQuery query = (AbstractQuery) target;
|
||||||
|
|
||||||
|
if (query.getFields() == null || query.getFields().isEmpty()) {
|
||||||
|
query.setFields(new LinkedHashSet<>(defaultResponseFields));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.getAggregations() == null || query.getAggregations().isEmpty()) {
|
||||||
|
query.setAggregations(new LinkedList<>(defaultResponseAggregations));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,9 +5,9 @@ import javax.annotation.Resource;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.TestExecutionListeners;
|
import org.springframework.test.context.TestExecutionListeners;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||||
@ -18,17 +18,16 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import ch.psi.daq.queryrest.config.QueryRestConfig;
|
||||||
import ch.psi.daq.test.cassandra.CassandraDaqUnitDependencyInjectionTestExecutionListener;
|
import ch.psi.daq.test.cassandra.CassandraDaqUnitDependencyInjectionTestExecutionListener;
|
||||||
|
|
||||||
|
|
||||||
@TestExecutionListeners({
|
@TestExecutionListeners({
|
||||||
CassandraDaqUnitDependencyInjectionTestExecutionListener.class,
|
CassandraDaqUnitDependencyInjectionTestExecutionListener.class,
|
||||||
DependencyInjectionTestExecutionListener.class})
|
DependencyInjectionTestExecutionListener.class})
|
||||||
//@SpringApplicationConfiguration(classes = {QueryRestApplication.class, DaqWebMvcConfig.class})
|
@SpringApplicationConfiguration(classes = {QueryRestConfig.class, DaqWebMvcConfig.class})
|
||||||
//@EmbeddedCassandra
|
|
||||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
@ContextConfiguration(classes = DaqWebMvcConfig.class)
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public abstract class AbstractDaqRestTest {
|
public abstract class AbstractDaqRestTest {
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp
|
|||||||
import ch.psi.daq.cassandra.reader.DataReader;
|
import ch.psi.daq.cassandra.reader.DataReader;
|
||||||
import ch.psi.daq.query.processor.QueryProcessor;
|
import ch.psi.daq.query.processor.QueryProcessor;
|
||||||
import ch.psi.daq.query.processor.cassandra.CassandraQueryProcessorLocal;
|
import ch.psi.daq.query.processor.cassandra.CassandraQueryProcessorLocal;
|
||||||
|
import ch.psi.daq.test.cassandra.admin.CassandraAdmin;
|
||||||
|
import ch.psi.daq.test.cassandra.admin.CassandraAdminImpl;
|
||||||
import ch.psi.daq.test.query.config.LocalQueryTestConfig;
|
import ch.psi.daq.test.query.config.LocalQueryTestConfig;
|
||||||
import ch.psi.daq.test.queryrest.query.DummyDataReader;
|
import ch.psi.daq.test.queryrest.query.DummyDataReader;
|
||||||
|
|
||||||
@ -36,4 +38,9 @@ public class DaqWebMvcConfig extends WebMvcConfigurationSupport {
|
|||||||
public DataReader dataReader() {
|
public DataReader dataReader() {
|
||||||
return new DummyDataReader();
|
return new DummyDataReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CassandraAdmin cassandraAdmin() {
|
||||||
|
return new CassandraAdminImpl();
|
||||||
|
}
|
||||||
}
|
}
|
@ -116,12 +116,14 @@ public class DaqRestControllerTest extends AbstractDaqRestTest {
|
|||||||
TEST_CHANNEL_NAMES);
|
TEST_CHANNEL_NAMES);
|
||||||
|
|
||||||
String content = mapper.writeValueAsString(request);
|
String content = mapper.writeValueAsString(request);
|
||||||
|
System.out.println(content);
|
||||||
|
|
||||||
this.mockMvc
|
this.mockMvc
|
||||||
.perform(MockMvcRequestBuilders.post(QueryRestController.QUERY)
|
.perform(
|
||||||
|
MockMvcRequestBuilders.post(QueryRestController.QUERY)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(content))
|
.content(content)
|
||||||
|
)
|
||||||
.andDo(MockMvcResultHandlers.print())
|
.andDo(MockMvcResultHandlers.print())
|
||||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
.andExpect(MockMvcResultMatchers.jsonPath("$").isArray())
|
.andExpect(MockMvcResultMatchers.jsonPath("$").isArray())
|
||||||
|
Reference in New Issue
Block a user