/**
* This file is part of lavagna.
*
* lavagna is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lavagna is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lavagna. If not, see <http://www.gnu.org/licenses/>.
*/
package io.lavagna.config;
import ch.digitalfondue.npjt.QueryFactory;
import ch.digitalfondue.npjt.QueryRepositoryScanner;
import io.lavagna.common.LavagnaEnvironment;
import org.apache.logging.log4j.LogManager;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.ErrorHandler;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* Datasource configuration.
*/
@EnableWebSocketMessageBroker
@EnableTransactionManagement
@ComponentScan(basePackages = { "io.lavagna.service", "io.lavagna.config.dbmanager" })
public class PersistenceAndServiceConfig extends AbstractWebSocketMessageBrokerConfigurer implements
SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskScheduler());
}
@Bean
public PlatformTransactionManager platformTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
private static class CustomSQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) {
// because mysql don't support check constraints :(
if (sqlex.getMessage().contains("RAISE_CHECK_ERROR")) {
return new DataIntegrityViolationException(task, sqlex);
}
return null;
}
}
@Bean
public NamedParameterJdbcTemplate simpleJdbcTemplate(LavagnaEnvironment env, DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// mysql does not support check constraints
if ("MYSQL".equals(env.getProperty("datasource.dialect"))) {
CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator();
tr.setDataSource(dataSource);
jdbcTemplate.setExceptionTranslator(tr);
}
return new NamedParameterJdbcTemplate(jdbcTemplate);
}
@Bean
public QueryRepositoryScanner queryRepoScanner(QueryFactory queryFactory) {
return new QueryRepositoryScanner(queryFactory, "io.lavagna.query");
}
@Bean
public QueryFactory queryFactory(LavagnaEnvironment env, NamedParameterJdbcTemplate jdbc) {
return new QueryFactory(env.getProperty("datasource.dialect"), jdbc);
}
@Bean
public LobHandler lobHander() {
return new DefaultLobHandler();
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
source.setBasename("classpath:/io/lavagna/i18n/messages");
source.setUseCodeAsDefaultMessage(true);
source.setFallbackToSystemLocale(false);
return source;
}
@Bean(destroyMethod = "shutdown")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setErrorHandler(new ErrorHandler() {
@Override
public void handleError(Throwable t) {
LogManager.getLogger().error("error while handling job", t);
}
});
scheduler.initialize();
return scheduler;
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/api/socket").withSockJS().setClientLibraryUrl("../../js/sockjs.min.js");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/event");
}
}