ATEST-827 and simplify SpringBoot app.
This commit is contained in:
@@ -1,32 +1,26 @@
|
||||
package ch.psi.daq.queryrest;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
* Entry point to our rest-frontend of the data acquisition (DAQ) application which most importantly
|
||||
* wires all the @RestController annotated classes.
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration(exclude={
|
||||
CassandraDataAutoConfiguration.class
|
||||
})
|
||||
//@EnableEncryptableProperties
|
||||
@SpringBootApplication(
|
||||
exclude = {
|
||||
CassandraDataAutoConfiguration.class
|
||||
},
|
||||
scanBasePackageClasses = {
|
||||
QueryRestApplication.class
|
||||
})
|
||||
//@EnableEncryptableProperties
|
||||
// http://stackoverflow.com/questions/26655875/spring-boot-redirect-http-to-https
|
||||
public class QueryRestApplication extends SpringBootServletInitializer {
|
||||
public class QueryRestApplication {
|
||||
|
||||
public static void main(final String[] args) {
|
||||
System.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
|
||||
SpringApplication.run(QueryRestApplication.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
|
||||
return application.sources(QueryRestApplication.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import ch.psi.daq.domain.query.operation.Aggregation;
|
||||
import ch.psi.daq.domain.query.operation.QueryField;
|
||||
import ch.psi.daq.domain.query.operation.aggregation.extrema.AbstractExtremaMeta;
|
||||
import ch.psi.daq.domain.query.response.Response;
|
||||
import ch.psi.daq.domain.request.validate.RequestProviderValidator;
|
||||
import ch.psi.daq.query.analyzer.BackendQueryAnalyzerImpl;
|
||||
import ch.psi.daq.query.config.QueryConfig;
|
||||
import ch.psi.daq.queryrest.controller.validator.QueryValidator;
|
||||
@@ -85,6 +86,7 @@ public class QueryRestConfig { // extends WebMvcConfigurerAdapter {
|
||||
public static final String BEAN_NAME_QUERY_MANAGER = "queryManager";
|
||||
public static final String BEAN_NAME_QUERY_ANALIZER_FACTORY = "queryAnalizerFactory";
|
||||
public static final String BEAN_NAME_QUERY_VALIDATOR = "queryValidator";
|
||||
public static final String BEAN_NAME_REQUEST_PROVIDER_VALIDATOR = "requestProviderValidator";
|
||||
public static final String BEAN_NAME_JSON_FACTORY = "jsonFactory";
|
||||
public static final String BEAN_NAME_MSG_PACK_FACTORY = "msgPackFactory";
|
||||
public static final String BEAN_NAME_SMILE_FACTORY = "smileFactory";
|
||||
@@ -126,28 +128,30 @@ public class QueryRestConfig { // extends WebMvcConfigurerAdapter {
|
||||
objectMapper.addMixIn(Response.class, PolymorphicResponseMixIn.class);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
// final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
// /**
|
||||
// * 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);
|
||||
// converters.add(converter);
|
||||
// super.configureMessageConverters(converters);
|
||||
// }
|
||||
|
||||
// does this work for json comming from web-requests
|
||||
// -> use WebMvcConfigurationSupport?
|
||||
// https://stackoverflow.com/questions/26639475/how-to-set-context-param-in-spring-boot
|
||||
// @Bean
|
||||
// @Lazy
|
||||
// public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
|
||||
// final MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
|
||||
// jsonConverter.setObjectMapper(objectMapper);
|
||||
// return jsonConverter;
|
||||
// }
|
||||
// @Override
|
||||
// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
// final MappingJackson2HttpMessageConverter converter = new
|
||||
// MappingJackson2HttpMessageConverter();
|
||||
// /**
|
||||
// * 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);
|
||||
// converters.add(converter);
|
||||
// super.configureMessageConverters(converters);
|
||||
// }
|
||||
|
||||
// does this work for json comming from web-requests
|
||||
// -> use WebMvcConfigurationSupport?
|
||||
// https://stackoverflow.com/questions/26639475/how-to-set-context-param-in-spring-boot
|
||||
// @Bean
|
||||
// @Lazy
|
||||
// public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
|
||||
// final MappingJackson2HttpMessageConverter jsonConverter = new
|
||||
// MappingJackson2HttpMessageConverter();
|
||||
// jsonConverter.setObjectMapper(objectMapper);
|
||||
// return jsonConverter;
|
||||
// }
|
||||
|
||||
@Bean(name = BEAN_NAME_JSON_FACTORY)
|
||||
@Lazy
|
||||
@@ -267,4 +271,10 @@ public class QueryRestConfig { // extends WebMvcConfigurerAdapter {
|
||||
public Validator queryValidator() {
|
||||
return new QueryValidator();
|
||||
}
|
||||
|
||||
@Bean(name = BEAN_NAME_REQUEST_PROVIDER_VALIDATOR)
|
||||
@Lazy
|
||||
public Validator requestProviderValidator() {
|
||||
return new RequestProviderValidator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package ch.psi.daq.queryrest.controller;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -15,6 +17,9 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.DirectFieldBindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
@@ -46,7 +51,6 @@ import ch.psi.daq.domain.query.response.Response;
|
||||
import ch.psi.daq.domain.query.response.ResponseFormat;
|
||||
import ch.psi.daq.domain.query.transform.image.color.ColorModelType;
|
||||
import ch.psi.daq.domain.query.transform.image.resize.ValueAggregation;
|
||||
import ch.psi.daq.domain.request.validate.RequestProviderValidator;
|
||||
import ch.psi.daq.queryrest.config.QueryRestConfig;
|
||||
import ch.psi.daq.queryrest.query.QueryManager;
|
||||
import ch.psi.daq.queryrest.response.AbstractHTTPResponse;
|
||||
@@ -63,7 +67,7 @@ public class QueryRestController implements ApplicationContextAware {
|
||||
private ObjectMapper objectMapper;
|
||||
private QueryManager queryManager;
|
||||
private Validator queryValidator;
|
||||
private Validator requestProviderValidator = new RequestProviderValidator();
|
||||
private Validator requestProviderValidator;
|
||||
private Response defaultResponse = new JSONHTTPResponse();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -77,6 +81,7 @@ public class QueryRestController implements ApplicationContextAware {
|
||||
objectMapper = context.getBean(DomainConfig.BEAN_NAME_OBJECT_MAPPER, ObjectMapper.class);
|
||||
queryManager = context.getBean(QueryRestConfig.BEAN_NAME_QUERY_MANAGER, QueryManager.class);
|
||||
queryValidator = context.getBean(QueryRestConfig.BEAN_NAME_QUERY_VALIDATOR, Validator.class);
|
||||
requestProviderValidator = context.getBean(QueryRestConfig.BEAN_NAME_REQUEST_PROVIDER_VALIDATOR, Validator.class);
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
@@ -146,8 +151,32 @@ public class QueryRestController implements ApplicationContextAware {
|
||||
value = DomainConfig.PATH_QUERY,
|
||||
method = RequestMethod.GET)
|
||||
public void executeQueryBodyAsString(@RequestParam String jsonBody, HttpServletResponse res) throws Exception {
|
||||
DAQQuery query = objectMapper.readValue(jsonBody, DAQQuery.class);
|
||||
executeQuery(query, res);
|
||||
DAQQuery query;
|
||||
try {
|
||||
query = objectMapper.readValue(jsonBody, DAQQuery.class);
|
||||
} catch (Exception e) {
|
||||
// somehow only needed for our test mokup environment (@RequestParam seems to do the
|
||||
// decoding on production server).
|
||||
LOGGER.info("Could not parse '{}' due to '{}'. Retry url decoded.", jsonBody, e.getMessage());
|
||||
query = objectMapper.readValue(URLDecoder.decode(jsonBody, StandardCharsets.UTF_8.name()), DAQQuery.class);
|
||||
}
|
||||
|
||||
final Errors errors = new DirectFieldBindingResult(query, query.getClass().getName());
|
||||
if (requestProviderValidator.supports(query.getClass())) {
|
||||
requestProviderValidator.validate(query, errors);
|
||||
}
|
||||
if (queryValidator.supports(query.getClass())) {
|
||||
queryValidator.validate(query, errors);
|
||||
}
|
||||
|
||||
final List<ObjectError> allErrors = errors.getAllErrors();
|
||||
if (allErrors.isEmpty()) {
|
||||
executeQuery(query, res);
|
||||
} else {
|
||||
final String message = String.format("Could not parse '%s' due to '%s'.", jsonBody, errors.toString());
|
||||
LOGGER.error(message);
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,8 +207,32 @@ public class QueryRestController implements ApplicationContextAware {
|
||||
value = DomainConfig.PATH_QUERIES,
|
||||
method = RequestMethod.GET)
|
||||
public void executeQueriesBodyAsString(@RequestParam String jsonBody, HttpServletResponse res) throws Exception {
|
||||
DAQQueries queries = objectMapper.readValue(jsonBody, DAQQueries.class);
|
||||
executeQueries(queries, res);
|
||||
DAQQueries queries;
|
||||
try {
|
||||
queries = objectMapper.readValue(jsonBody, DAQQueries.class);
|
||||
} catch (Exception e) {
|
||||
// somehow only needed for our test mokup environment (@RequestParam seems to do the
|
||||
// decoding on production server).
|
||||
LOGGER.info("Could not parse '{}' due to '{}'. Retry url decoded.", jsonBody, e.getMessage());
|
||||
queries = objectMapper.readValue(URLDecoder.decode(jsonBody, StandardCharsets.UTF_8.name()), DAQQueries.class);
|
||||
}
|
||||
|
||||
final Errors errors = new DirectFieldBindingResult(queries, queries.getClass().getName());
|
||||
if (requestProviderValidator.supports(queries.getClass())) {
|
||||
requestProviderValidator.validate(queries, errors);
|
||||
}
|
||||
if (queryValidator.supports(queries.getClass())) {
|
||||
queryValidator.validate(queries, errors);
|
||||
}
|
||||
|
||||
final List<ObjectError> allErrors = errors.getAllErrors();
|
||||
if (allErrors.isEmpty()) {
|
||||
executeQueries(queries, res);
|
||||
} else {
|
||||
final String message = String.format("Could not parse '%s' due to '%s'.", jsonBody, errors.toString());
|
||||
LOGGER.error(message);
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,4 +12,4 @@ filestorage.reader.local=false
|
||||
filestorage.compaction.startup.init=false
|
||||
filestorage.startup.repair.init=false
|
||||
|
||||
# server.port=8081
|
||||
#server.port=8081
|
||||
@@ -15,6 +15,7 @@ import java.util.Set;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -492,7 +493,7 @@ public class CSVQueryRestControllerTest extends AbstractDaqRestTest {
|
||||
assertEquals("" + TimeUtils.getMillis(TestTimeUtils.getTimeFromPulseId(pulse)), record.get(column++));
|
||||
assertEquals("[8]", record.get(column++));
|
||||
assertEquals("1", record.get(column++));
|
||||
assertTrue(record.get(column).startsWith("["+pulse+","));
|
||||
assertTrue(record.get(column).startsWith("[" + pulse + ","));
|
||||
assertTrue(record.get(column++).endsWith("]"));
|
||||
}
|
||||
++pulse;
|
||||
@@ -1020,6 +1021,11 @@ public class CSVQueryRestControllerTest extends AbstractDaqRestTest {
|
||||
String response = result.getResponse().getContentAsString();
|
||||
System.out.println("Response: " + response);
|
||||
|
||||
checkDateRangeQueryBinSizeAggregate(channels, aggregations, queryFields, response);
|
||||
}
|
||||
|
||||
private void checkDateRangeQueryBinSizeAggregate(final List<String> channels, final List<Aggregation> aggregations,
|
||||
final Set<QueryField> queryFields, final String response) throws Exception {
|
||||
CSVFormat csvFormat = CSVFormat.EXCEL.withDelimiter(CSVResponseStreamWriter.DELIMITER_CVS);
|
||||
StringReader reader = new StringReader(response);
|
||||
CSVParser csvParser = new CSVParser(reader, csvFormat);
|
||||
@@ -1073,6 +1079,61 @@ public class CSVQueryRestControllerTest extends AbstractDaqRestTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateRangeQueryBinSizeAggregate_GET() throws Exception {
|
||||
List<String> channels = Arrays.asList(TEST_CHANNEL_01);
|
||||
long startTime = 0;
|
||||
long endTime = 999;
|
||||
String startDate = TimeUtils.format(startTime);
|
||||
String endDate = TimeUtils.format(endTime);
|
||||
List<Aggregation> aggregations = new ArrayList<>();
|
||||
aggregations.add(Aggregation.min);
|
||||
aggregations.add(Aggregation.mean);
|
||||
aggregations.add(Aggregation.max);
|
||||
|
||||
DAQQuery request = new DAQQuery(
|
||||
new RequestRangeDate(
|
||||
startDate,
|
||||
endDate),
|
||||
channels);
|
||||
// request.setAggregation(new
|
||||
// AggregationDescriptor().setDurationPerBin(100).setAggregations(aggregations));
|
||||
// make sure defaults are set
|
||||
request.setAggregation(new AggregationDescriptor().setDurationPerBin(100));
|
||||
request.setResponse(new CSVHTTPResponse());
|
||||
|
||||
LinkedHashSet<QueryField> queryFields = new LinkedHashSet<>();
|
||||
queryFields.add(QueryField.channel);
|
||||
queryFields.add(QueryField.pulseId);
|
||||
queryFields.add(QueryField.iocSeconds);
|
||||
queryFields.add(QueryField.iocMillis);
|
||||
queryFields.add(QueryField.globalSeconds);
|
||||
queryFields.add(QueryField.globalMillis);
|
||||
queryFields.add(QueryField.shape);
|
||||
queryFields.add(QueryField.eventCount);
|
||||
request.setFields(queryFields);
|
||||
|
||||
String content = mapper.writeValueAsString(request);
|
||||
System.out.println(content);
|
||||
|
||||
URIBuilder ub = new URIBuilder(DomainConfig.PATH_QUERY);
|
||||
ub.addParameter(DomainConfig.PATH_QUERY_PARAM_JSON_BODY, content);
|
||||
String url = ub.toString();
|
||||
System.out.println(url);
|
||||
|
||||
MvcResult result = this.mockMvc
|
||||
.perform(MockMvcRequestBuilders
|
||||
.get(url))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andReturn();
|
||||
|
||||
String response = result.getResponse().getContentAsString();
|
||||
System.out.println("Response: " + response);
|
||||
|
||||
checkDateRangeQueryBinSizeAggregate(channels, aggregations, queryFields, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuery_NoTimeFields_01() throws Exception {
|
||||
List<String> channels = Arrays.asList(TEST_CHANNEL_01, TEST_CHANNEL_02);
|
||||
|
||||
@@ -19,17 +19,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ch.psi.daq.domain.backend.Backend;
|
||||
import ch.psi.daq.domain.config.DomainConfig;
|
||||
import ch.psi.daq.domain.query.DAQQuery;
|
||||
import ch.psi.daq.domain.query.operation.Aggregation;
|
||||
import ch.psi.daq.domain.query.operation.AggregationDescriptor;
|
||||
import ch.psi.daq.domain.query.operation.Compression;
|
||||
import ch.psi.daq.domain.query.response.Response;
|
||||
import ch.psi.daq.domain.request.range.RequestRangeDate;
|
||||
import ch.psi.daq.domain.request.range.RequestRangePulseId;
|
||||
import ch.psi.daq.queryrest.response.csv.CSVHTTPResponse;
|
||||
import ch.psi.daq.queryrest.response.json.JSONHTTPResponse;
|
||||
import ch.psi.daq.test.queryrest.AbstractDaqRestTest;
|
||||
|
||||
public class ResponseQueryTest extends AbstractDaqRestTest{
|
||||
public class ResponseQueryTest extends AbstractDaqRestTest {
|
||||
|
||||
@Resource(name = DomainConfig.BEAN_NAME_BACKEND_DEFAULT)
|
||||
private Backend backend;
|
||||
@@ -74,26 +71,6 @@ public class ResponseQueryTest extends AbstractDaqRestTest{
|
||||
assertEquals(query.getResponse().getCompression().getFileSuffix(), deserial.getResponse().getFileSuffix());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_JSON_02_01() throws JsonParseException, JsonMappingException, IOException {
|
||||
DAQQuery query = new DAQQuery(
|
||||
new RequestRangeDate(
|
||||
"2017-09-25T19:00:05.319+02:00",
|
||||
"2017-09-25T19:03:05.319+02:00"),
|
||||
new AggregationDescriptor().setDurationPerBin(100),
|
||||
"TestChannel_01");
|
||||
query.setResponse(new CSVHTTPResponse(Compression.GZIP));
|
||||
|
||||
// String value = mapper.writeValueAsString(query);
|
||||
String value = "{\"channels\":[{\"backend\":\"queryrest-1\",\"name\":\"TestChannel_01\"}],\"fields\":[\"globalMillis\",\"globalDate\",\"value\",\"shape\",\"eventCount\"],\"range\":{\"startDate\":\"2017-09-25T19:02:57.318+02:00\",\"endDate\":\"2017-09-25T19:03:05.319+02:00\"},\"aggregation\":{\"durationPerBin\":\"PT15M\"},\"response\":{\"format\":\"csv\",\"compression\":\"none\"}}";
|
||||
// System.out.println(value);
|
||||
DAQQuery deserial = mapper.readValue(value, DAQQuery.class);
|
||||
|
||||
assertNotNull(deserial.getResponse());
|
||||
assertEquals(query.getResponse().getClass(), deserial.getResponse().getClass());
|
||||
assertEquals(query.getResponse().getCompression(), deserial.getResponse().getCompression());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_JSON_03() throws JsonParseException, JsonMappingException, IOException {
|
||||
DAQQuery query = new DAQQuery(
|
||||
|
||||
Reference in New Issue
Block a user