package gov.nysenate.openleg.config;
import gov.nysenate.openleg.util.AsciiArt;
import gov.nysenate.openleg.util.OpenlegThreadFactory;
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.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import javax.annotation.PostConstruct;
import javax.xml.transform.Source;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
@ComponentScan("gov.nysenate.openleg")
@Import({DatabaseConfig.class, SecurityConfig.class, ApplicationConfig.class, WebSocketsConfig.class})
public class WebApplicationConfig extends WebMvcConfigurerAdapter implements SchedulingConfigurer,
AsyncConfigurer
{
private static final Logger logger = LoggerFactory.getLogger(WebApplicationConfig.class);
private static final String resourcePath = "/static/**";
private static final String resourceLocation = "/static/";
@Autowired ApplicationConfig appConfig;
@PostConstruct
public void init() {
logger.info("{}", AsciiArt.OPENLEG_2_LOGO.getText().replace("DATE", LocalDateTime.now().toString()));
}
/** Sets paths that should not be intercepted by a controller (e.g css/ js/). */
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.info("Registering resource path {} for files under {}", resourcePath, resourceLocation);
registry.addResourceHandler(resourcePath).addResourceLocations(resourceLocation).setCachePeriod(64000);
}
/**
* This view resolver will map view names returned from the controllers to jsp files stored in the
* configured 'prefix' url.
*/
@Bean(name = "viewResolver")
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setWriteAcceptCharset(false);
converters.add(new ByteArrayHttpMessageConverter());
converters.add(stringConverter);
converters.add(new ResourceHttpMessageConverter());
converters.add(new SourceHttpMessageConverter<Source>());
converters.add(new AllEncompassingFormHttpMessageConverter());
converters.add(new Jaxb2RootElementHttpMessageConverter());
converters.add(jackson2Converter());
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
@Bean
public MappingJackson2HttpMessageConverter jackson2Converter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(appConfig.objectMapper());
return converter;
}
@Bean(name = "openlegScheduler", destroyMethod = "shutdownNow")
public ScheduledExecutorService schedulerThreadPool() {
return Executors.newScheduledThreadPool(4, new OpenlegThreadFactory("scheduler"));
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(schedulerThreadPool());
}
@Override
@Bean(name = "openlegAsync", destroyMethod = "shutdown")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadFactory(new OpenlegThreadFactory("spring-async"));
executor.setCorePoolSize(10);
executor.initialize();
return executor;
}
}