Subversion Repositories SmartDukaan

Rev

Rev 35828 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.dao.config;

import java.io.IOException;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties;

import javax.annotation.PreDestroy;
import javax.sql.DataSource;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.hibernate.SessionFactory;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
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.Primary;
import org.springframework.core.io.Resource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.spice.profitmandi.dao.repository.dtr.Mongo;

import com.spice.profitmandi.web.config.AppConfig;


@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.spice.profitmandi.*" })
public class WebDBContextConfigure {

        private static final Logger LOGGER = LogManager.getLogger(WebDBContextConfigure.class);

        private static final String HIBERNATE_DRIVER_CLASS = "hibernate.driver.class";
        private static final String HIBERNATE_URL = "hibernate.url";
        private static final String HIBERNATE_USER_NAME = "hibernate.user.name";
        private static final String HIBERNATE_PASSWORD = "hibernate.password";
        private 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";
        private static final String HIBERNATE_ORDER_INSERTS = "hibernate.order_inserts";
        private static final String HIBERNATE_ORDER_UPDATES = "hibernate.order_updates";
        private 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";

        private Resource resource = AppConfig.getResource();

        private Properties loadAllProperties() {
                Properties properties = new Properties();
                try {
                        Resource sharedRes = AppConfig.getSharedResource();
                        if (sharedRes != null && sharedRes.exists()) {
                                properties.load(sharedRes.getInputStream());
                        }
                        properties.load(resource.getInputStream());
                } catch (IOException e) {
                        LOGGER.error("Failed to load properties", e);
                }
                return properties;
        }

        @Bean(name = "dataSource", destroyMethod = "close")
        public DataSource dataSource() {
                Properties properties = loadAllProperties();

                HikariConfig config = new HikariConfig();
                config.setDriverClassName(properties.getProperty(HIBERNATE_DRIVER_CLASS));
                config.setJdbcUrl(properties.getProperty(HIBERNATE_URL));
                config.setUsername(properties.getProperty(HIBERNATE_USER_NAME));
                config.setPassword(properties.getProperty(HIBERNATE_PASSWORD));
                config.setMaximumPoolSize(Integer.parseInt(properties.getProperty(HIKARI_MAX_POOL_SIZE, "20")));
                config.setMinimumIdle(Integer.parseInt(properties.getProperty(HIKARI_MIN_IDLE, "2")));
                config.setIdleTimeout(Long.parseLong(properties.getProperty(HIKARI_IDLE_TIMEOUT, "30000")));
                config.setMaxLifetime(Long.parseLong(properties.getProperty(HIKARI_MAX_LIFETIME, "1800000")));
                config.setConnectionTimeout(Long.parseLong(properties.getProperty(HIKARI_CONNECTION_TIMEOUT, "30000")));
                config.setPoolName("HikariPool-Web");
                config.setLeakDetectionThreshold(30000);

                LOGGER.info("Initializing HikariDataSource with URL: {}", properties.getProperty(HIBERNATE_URL));
                return new HikariDataSource(config);
        }

        @Bean
        public Properties getHibernateProperties() {
                Properties dbProperties = new Properties();
                Properties properties = loadAllProperties();
                dbProperties.put(HIBERNATE_DIALECT, properties.getProperty(HIBERNATE_DIALECT));
                dbProperties.put(HIBERNATE_SHOW_SQL, properties.getProperty(HIBERNATE_SHOW_SQL));
                dbProperties.put(HIBERNATE_FORMAT_SQL, properties.getProperty(HIBERNATE_FORMAT_SQL));
                dbProperties.put(HIBERNATE_JDBC_BATCH_SIZE, properties.getProperty(HIBERNATE_JDBC_BATCH_SIZE));
                dbProperties.put(HIBERNATE_ORDER_INSERTS, properties.getProperty(HIBERNATE_ORDER_INSERTS, "true"));
                dbProperties.put(HIBERNATE_ORDER_UPDATES, properties.getProperty(HIBERNATE_ORDER_UPDATES, "true"));
                return dbProperties;
        }

        @Primary
        @Bean(name = "sessionFactory")
        public 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();
        }

        @Primary
        @Bean(name = "transactionManager")
        public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
                return new HibernateTransactionManager(sessionFactory);
        }
        
        @Bean(destroyMethod = "close")
        public Mongo mongoClient() {
                Properties properties = loadAllProperties();
                return new Mongo(properties.getProperty("mongo.host"), properties.getProperty("content.mongo.host"));
        }

        /**
         * Cleanup method to prevent memory leaks on shutdown.
         * Deregisters JDBC drivers and stops MySQL cleanup thread.
         */
        @PreDestroy
        public void cleanup() {
                LOGGER.info("WebDBContextConfigure cleanup started...");

                // Stop MySQL AbandonedConnectionCleanupThread
                try {
                        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 classloader
                ClassLoader 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("WebDBContextConfigure cleanup completed");
        }
}