Rev 34690 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.smartdukaan.cron.config;import com.fasterxml.jackson.databind.DeserializationFeature;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.spice.profitmandi.dao.convertor.LocalDateJsonConverter;import com.spice.profitmandi.dao.convertor.LocalDateTimeJsonConverter;import com.spice.profitmandi.dao.repository.dtr.Mongo;import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;import com.zaxxer.hikari.HikariConfig;import com.zaxxer.hikari.HikariDataSource;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.*;import org.springframework.core.env.Environment;import org.springframework.jdbc.datasource.DriverManagerDataSource;import org.springframework.orm.hibernate5.HibernateTransactionManager;import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.PreDestroy;import javax.sql.DataSource;import java.sql.Driver;import java.sql.DriverManager;import java.sql.SQLException;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.time.format.DateTimeFormatterBuilder;import java.util.Enumeration;import java.util.Properties;@Configuration@EnableTransactionManagement@ComponentScan("com.spice.profitmandi.*")@PropertySource(value = {"classpath:shared-dev.properties", "classpath:META-INF/env.properties"}, ignoreResourceNotFound = true)public class DBConfig {private static final Logger LOGGER = LogManager.getLogger(DBConfig.class);// Hibernate Property Keysprivate static final String HIBERNATE_DIALECT = "hibernate.dialect";private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";private static final String HIBERNATE_FORMAT_SQL = "hibernate.format_sql";private static final String HIBERNATE_JDBC_BATCH_SIZE = "hibernate.jdbc.batch_size";// HikariCP Propertiesprivate static final String HIKARI_MAX_POOL_SIZE = "hikari.maximumPoolSize";private static final String HIKARI_MIN_IDLE = "hikari.minimumIdle";private static final String HIKARI_IDLE_TIMEOUT = "hikari.idleTimeout";private static final String HIKARI_MAX_LIFETIME = "hikari.maxLifetime";private static final String HIKARI_CONNECTION_TIMEOUT = "hikari.connectionTimeout";// Injected DB Properties@Value("${hibernate.driver.class}")private String hibernateDriverClass;@Value("${hibernate.url}")private String hibernateUrl;@Value("${hibernate.user.name}")private String hibernateUserName;@Value("${hibernate.password}")private String hibernatePassword;@Value("${hibernate.dialect}")private String hibernateDialect;@Value("${hibernate.show_sql}")private String hibernateShowSql;@Value("${hibernate.format_sql}")private String hibernateFormatSql;@Value("${hibernate.jdbc.batch_size}")private String hibernateBatchSize;// Mongo Config@Value("${mongo.host}")private String mongoHost;@Value("${content.mongo.host}")private String contentMongoHost;@Autowiredprivate Environment env;/*** Primary DataSource using DriverManager (can be replaced with HikariDataSource)*/@Primary@Bean(name = "dataSource", destroyMethod = "close")public HikariDataSource dataSource() {HikariConfig config = new HikariConfig();config.setDriverClassName(hibernateDriverClass);config.setJdbcUrl(hibernateUrl);config.setUsername(hibernateUserName);config.setPassword(hibernatePassword);config.setMaximumPoolSize(Integer.parseInt(env.getProperty(HIKARI_MAX_POOL_SIZE, "20")));config.setMinimumIdle(Integer.parseInt(env.getProperty(HIKARI_MIN_IDLE, "2")));config.setIdleTimeout(Long.parseLong(env.getProperty(HIKARI_IDLE_TIMEOUT, "30000")));config.setMaxLifetime(Long.parseLong(env.getProperty(HIKARI_MAX_LIFETIME, "1800000")));config.setConnectionTimeout(Long.parseLong(env.getProperty(HIKARI_CONNECTION_TIMEOUT, "30000")));config.setPoolName("HikariPool");config.setAutoCommit(true);HikariDataSource dataSource = new HikariDataSource(config);LOGGER.info("HikariDataSource initialized with JDBC URL {}", hibernateUrl);return dataSource;}/*** Configure Hibernate properties*/@Beanpublic Properties getHibernateProperties() {Properties dbProperties = new Properties();dbProperties.put(HIBERNATE_DIALECT, hibernateDialect);dbProperties.put(HIBERNATE_SHOW_SQL, hibernateShowSql);dbProperties.put(HIBERNATE_FORMAT_SQL, hibernateFormatSql);dbProperties.put(HIBERNATE_JDBC_BATCH_SIZE, hibernateBatchSize);// HikariCP properties (Optional — Spring Boot auto-configures most)//dbProperties.put("hibernate.connection.provider_class", "org.hibernate.hikaricp.internal.HikariCPConnectionProvider");return dbProperties;}/*** Configure Hibernate SessionFactory*/@Primary@Bean(name = "sessionFactory")@Autowiredpublic SessionFactory getSessionFactory(DataSource dataSource) {LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);sessionBuilder.addProperties(getHibernateProperties());sessionBuilder.scanPackages("com.spice.profitmandi.dao.*");LOGGER.info("SessionFactory created");return sessionBuilder.buildSessionFactory();}/*** Transaction Manager*/@Primary@Bean(name = "transactionManager")@Autowiredpublic HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);LOGGER.info("TransactionManager created");return transactionManager;}/*** ObjectMapper Bean with Java 8 Time module config*/@Beanpublic ObjectMapper objectMapper() {DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ISO_LOCAL_DATE).optionalStart().appendLiteral('T').optionalEnd().appendLiteral(' ').append(DateTimeFormatter.ISO_LOCAL_TIME).toFormatter();DateTimeFormatter standardFormatter = new DateTimeFormatterBuilder().parseCaseInsensitive().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T').append(DateTimeFormatter.ISO_LOCAL_TIME).toFormatter();JavaTimeModule javaTimeModule = new JavaTimeModule();javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(standardFormatter));javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE));ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).registerModule(new ParameterNamesModule()).registerModule(new Jdk8Module()).registerModule(javaTimeModule);LOGGER.info("ObjectMapper configured");return mapper;}/*** Mongo Client Bean*/@Bean(destroyMethod = "close")public Mongo mongoClient(SessionFactory sessionFactory) {return new Mongo(mongoHost, contentMongoHost);}/*** Gson Bean for LocalDate and LocalDateTime*/@Bean(name = "gson")public Gson gson() {Gson gson = new GsonBuilder().serializeNulls().registerTypeAdapter(LocalDate.class, new LocalDateJsonConverter()).registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonConverter()).create();LOGGER.info("Gson configured");return gson;}/*** Cleanup method to prevent memory leaks on shutdown.* Deregisters JDBC drivers and stops MySQL cleanup thread.*/@PreDestroypublic void cleanup() {LOGGER.info("DBConfig cleanup started...");// Stop MySQL AbandonedConnectionCleanupThreadtry {AbandonedConnectionCleanupThread.checkedShutdown();LOGGER.info("MySQL AbandonedConnectionCleanupThread stopped");} catch (Exception e) {LOGGER.error("Error stopping MySQL cleanup thread", e);}// Deregister JDBC drivers loaded by this webapp's classloaderClassLoader cl = Thread.currentThread().getContextClassLoader();Enumeration<Driver> drivers = DriverManager.getDrivers();while (drivers.hasMoreElements()) {Driver driver = drivers.nextElement();if (driver.getClass().getClassLoader() == cl) {try {DriverManager.deregisterDriver(driver);LOGGER.info("Deregistered JDBC driver: {}", driver);} catch (SQLException e) {LOGGER.error("Error deregistering JDBC driver {}", driver, e);}}}LOGGER.info("DBConfig cleanup completed");}}