diff --git a/src/main/java/ch/psi/daq/rest/DaqRestConfiguration.java b/src/main/java/ch/psi/daq/rest/DaqRestConfiguration.java deleted file mode 100644 index e7507cf..0000000 --- a/src/main/java/ch/psi/daq/rest/DaqRestConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -package ch.psi.daq.rest; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; - -import ch.psi.daq.common.statistic.StorelessStatistics; -import ch.psi.daq.domain.cassandra.ChannelEvent; -import ch.psi.daq.hazelcast.query.processor.QueryProcessor; -import ch.psi.daq.hazelcast.query.processor.cassandra.CassandraQueryProcessorDistributed; -import ch.psi.daq.rest.model.PropertyFilterMixin; - -@Configuration -public class DaqRestConfiguration { - - @Bean - public QueryProcessor queryProcessor() { - return new CassandraQueryProcessorDistributed(); - } - - @Bean - public JsonFactory jsonFactory() { - return new JsonFactory(); - } - - @Bean - public ResponseStreamWriter responseStreamWriter() { - return new ResponseStreamWriter(); - } - - @Bean - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); - // 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(ChannelEvent.class, PropertyFilterMixin.class); - mapper.addMixIn(StorelessStatistics.class, PropertyFilterMixin.class); - return mapper; - } - - // a nested configuration - // this guarantees that the ordering of the properties file is as expected - // see: - // https://jira.spring.io/browse/SPR-10409?focusedCommentId=101393&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-101393 - // @Configuration - // @Import(CassandraConfig.class) - // static class InnerConfiguration { } -} diff --git a/src/main/java/ch/psi/daq/rest/DaqRestApplication.java b/src/main/java/ch/psi/daq/rest/RestApplication.java similarity index 90% rename from src/main/java/ch/psi/daq/rest/DaqRestApplication.java rename to src/main/java/ch/psi/daq/rest/RestApplication.java index 3832b2b..86a2c04 100644 --- a/src/main/java/ch/psi/daq/rest/DaqRestApplication.java +++ b/src/main/java/ch/psi/daq/rest/RestApplication.java @@ -30,23 +30,23 @@ import org.springframework.context.annotation.ComponentScan; // @Import(CassandraConfig.class) // either define the context to be imported, or see ComponentScan // comment below @ComponentScan(basePackages = { - "ch.psi.daq.rest", - "ch.psi.daq.hazelcast", "ch.psi.daq.cassandra.config", // define the package name with the CassandraConfig // configuration, or @Import it (see above) "ch.psi.daq.cassandra.reader", - "ch.psi.daq.cassandra.writer" + "ch.psi.daq.cassandra.writer", + "ch.psi.daq.hazelcast", + "ch.psi.daq.rest", }) -public class DaqRestApplication extends SpringBootServletInitializer { +public class RestApplication extends SpringBootServletInitializer { public static void main(final String[] args) { - SpringApplication.run(DaqRestApplication.class, args); + SpringApplication.run(RestApplication.class, args); } @Override protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) { - return application.sources(DaqRestApplication.class); + return application.sources(RestApplication.class); } } diff --git a/src/main/java/ch/psi/daq/rest/config/RestConfiguration.java b/src/main/java/ch/psi/daq/rest/config/RestConfiguration.java new file mode 100644 index 0000000..d904006 --- /dev/null +++ b/src/main/java/ch/psi/daq/rest/config/RestConfiguration.java @@ -0,0 +1,102 @@ +package ch.psi.daq.rest.config; + +import java.util.Arrays; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hazelcast.client.HazelcastClient; +import com.hazelcast.client.config.ClientConfig; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.ManagedContext; +import com.hazelcast.spring.context.SpringManagedContext; + +import ch.psi.daq.common.statistic.StorelessStatistics; +import ch.psi.daq.domain.cassandra.ChannelEvent; +import ch.psi.daq.hazelcast.config.HazelcastConfig; +import ch.psi.daq.hazelcast.query.processor.QueryProcessor; +import ch.psi.daq.hazelcast.query.processor.cassandra.CassandraQueryProcessorDistributed; +import ch.psi.daq.rest.ResponseStreamWriter; +import ch.psi.daq.rest.model.PropertyFilterMixin; + +@Configuration +@PropertySource(value = { "classpath:rest.properties" }) +@PropertySource(value = { "file:${user.home}/.config/daq/rest.properties" }, ignoreResourceNotFound = true) +public class RestConfiguration { + + private static final Logger logger = LoggerFactory.getLogger(RestConfiguration.class); + + @Autowired + private Environment env; + + @Bean + public QueryProcessor queryProcessor() { + return new CassandraQueryProcessorDistributed(); + } + + @Bean + public JsonFactory jsonFactory() { + return new JsonFactory(); + } + + @Bean + public ResponseStreamWriter responseStreamWriter() { + return new ResponseStreamWriter(); + } + + @Bean(name = HazelcastConfig.BEAN_NAME_HAZELCAST_CLIENT) + public HazelcastInstance hazelcastClientInstance() { + return HazelcastClient.newHazelcastClient(hazelcastClientConfig()); + } + + private ClientConfig hazelcastClientConfig() { + ClientConfig config = new ClientConfig(); + config.setManagedContext(managedContext()); + + config.getNetworkConfig().setAddresses(hazelcastMembers()); + + return config; + } + + + private ManagedContext managedContext() { + return new SpringManagedContext(); + } + + @Bean + public List hazelcastMembers() { + List clusterMembers = Arrays.asList(StringUtils.commaDelimitedListToStringArray(env.getProperty("hazelcast.initialcandidates"))); + logger.info("The following hosts have been defined to form a Hazelcast cluster: {}", clusterMembers); + return clusterMembers; + } + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper mapper = new ObjectMapper(); + // 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(ChannelEvent.class, PropertyFilterMixin.class); + mapper.addMixIn(StorelessStatistics.class, PropertyFilterMixin.class); + return mapper; + } + + // a nested configuration + // this guarantees that the ordering of the properties file is as expected + // see: + // https://jira.spring.io/browse/SPR-10409?focusedCommentId=101393&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-101393 + // @Configuration + // @Import(CassandraConfig.class) + // static class InnerConfiguration { } +} diff --git a/src/main/java/ch/psi/daq/rest/DaqRestController.java b/src/main/java/ch/psi/daq/rest/controller/DaqRestController.java similarity index 97% rename from src/main/java/ch/psi/daq/rest/DaqRestController.java rename to src/main/java/ch/psi/daq/rest/controller/DaqRestController.java index 5d14b55..a9ea4c8 100644 --- a/src/main/java/ch/psi/daq/rest/DaqRestController.java +++ b/src/main/java/ch/psi/daq/rest/controller/DaqRestController.java @@ -1,4 +1,4 @@ -package ch.psi.daq.rest; +package ch.psi.daq.rest.controller; import java.io.IOException; import java.util.Map; @@ -19,6 +19,7 @@ import ch.psi.daq.cassandra.writer.CassandraWriter; import ch.psi.daq.domain.cassandra.ChannelEvent; import ch.psi.daq.domain.cassandra.DataEvent; import ch.psi.daq.hazelcast.query.processor.QueryProcessor; +import ch.psi.daq.rest.ResponseStreamWriter; import ch.psi.daq.rest.queries.AbstractQuery; import ch.psi.daq.rest.queries.PulseRangeQuery; import ch.psi.daq.rest.queries.TimeRangeQuery; diff --git a/src/main/resources/rest.properties b/src/main/resources/rest.properties index 653644d..9873024 100644 --- a/src/main/resources/rest.properties +++ b/src/main/resources/rest.properties @@ -1,3 +1,6 @@ +# port for the Spring boot application's embedded Tomcat server server.port=8080 -cassandra.basekeyspace=daq_zellweger_rest \ No newline at end of file +# defines the list of hosts who are tried for an initial connection to the cluster +#hazelcast.members=sf-nube-11.psi.ch,sf-nube-12.psi.ch,sf-nube-13.psi.ch,sf-nube-14.psi.ch +hazelcast.initialcandidates=localhost \ No newline at end of file diff --git a/src/test/java/ch/psi/daq/test/rest/AbstractDaqRestTest.java b/src/test/java/ch/psi/daq/test/rest/AbstractDaqRestTest.java index 583bbce..f2537d5 100644 --- a/src/test/java/ch/psi/daq/test/rest/AbstractDaqRestTest.java +++ b/src/test/java/ch/psi/daq/test/rest/AbstractDaqRestTest.java @@ -16,13 +16,13 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import ch.psi.daq.rest.DaqRestApplication; +import ch.psi.daq.rest.RestApplication; import ch.psi.daq.test.cassandra.CassandraDaqUnitDependencyInjectionTestExecutionListener; import com.fasterxml.jackson.databind.ObjectMapper; -@SpringApplicationConfiguration(classes = {DaqRestApplication.class, DaqRestApplicationConfiguration.class}) +@SpringApplicationConfiguration(classes = {RestApplication.class, DaqWebMvcConfiguration.class}) @TestExecutionListeners({ CassandraDaqUnitDependencyInjectionTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) diff --git a/src/test/java/ch/psi/daq/test/rest/DaqRestApplicationConfiguration.java b/src/test/java/ch/psi/daq/test/rest/DaqWebMvcConfiguration.java similarity index 78% rename from src/test/java/ch/psi/daq/test/rest/DaqRestApplicationConfiguration.java rename to src/test/java/ch/psi/daq/test/rest/DaqWebMvcConfiguration.java index 0a49467..0ab6185 100644 --- a/src/test/java/ch/psi/daq/test/rest/DaqRestApplicationConfiguration.java +++ b/src/test/java/ch/psi/daq/test/rest/DaqWebMvcConfiguration.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Import; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; -import ch.psi.daq.rest.DaqRestConfiguration; +import ch.psi.daq.rest.config.RestConfiguration; import ch.psi.daq.test.cassandra.LocalCassandraTestConfig; @Configuration @@ -16,9 +16,9 @@ import ch.psi.daq.test.cassandra.LocalCassandraTestConfig; // "ch.psi.daq.cassandra.reader", // "ch.psi.daq.cassandra.writer" //}) -@Import(value = {LocalCassandraTestConfig.class, DaqRestConfiguration.class}) +@Import(value = {LocalCassandraTestConfig.class, RestConfiguration.class}) @EnableWebMvc -public class DaqRestApplicationConfiguration extends WebMvcConfigurationSupport { +public class DaqWebMvcConfiguration extends WebMvcConfigurationSupport { // add test-specific beans and configurations here } \ No newline at end of file