Subversion Repositories SmartDukaan

Rev

Rev 35586 | Rev 35830 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
23723 amit.gupta 1
package com.smartdukaan.cron.config;
2
 
32185 amit.gupta 3
import com.fasterxml.jackson.databind.DeserializationFeature;
24433 amit.gupta 4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
6
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
29859 amit.gupta 7
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
24433 amit.gupta 8
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
29859 amit.gupta 9
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
24433 amit.gupta 10
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
11
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
25721 tejbeer 12
import com.google.gson.Gson;
13
import com.google.gson.GsonBuilder;
29838 tejbeer 14
import com.spice.profitmandi.dao.convertor.LocalDateJsonConverter;
25721 tejbeer 15
import com.spice.profitmandi.dao.convertor.LocalDateTimeJsonConverter;
23738 amit.gupta 16
import com.spice.profitmandi.dao.repository.dtr.Mongo;
34690 amit.gupta 17
 
35393 amit 18
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
34690 amit.gupta 19
import com.zaxxer.hikari.HikariConfig;
20
import com.zaxxer.hikari.HikariDataSource;
30307 amit.gupta 21
import org.apache.logging.log4j.LogManager;
22
import org.apache.logging.log4j.Logger;
23
import org.hibernate.SessionFactory;
24
import org.springframework.beans.factory.annotation.Autowired;
25
import org.springframework.beans.factory.annotation.Value;
26
import org.springframework.context.annotation.*;
34690 amit.gupta 27
import org.springframework.core.env.Environment;
30307 amit.gupta 28
import org.springframework.jdbc.datasource.DriverManagerDataSource;
29
import org.springframework.orm.hibernate5.HibernateTransactionManager;
30
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
31
import org.springframework.transaction.annotation.EnableTransactionManagement;
23738 amit.gupta 32
 
35393 amit 33
import javax.annotation.PreDestroy;
30307 amit.gupta 34
import javax.sql.DataSource;
35393 amit 35
import java.sql.Driver;
36
import java.sql.DriverManager;
37
import java.sql.SQLException;
30307 amit.gupta 38
import java.time.LocalDate;
39
import java.time.LocalDateTime;
40
import java.time.format.DateTimeFormatter;
41
import java.time.format.DateTimeFormatterBuilder;
35393 amit 42
import java.util.Enumeration;
30307 amit.gupta 43
import java.util.Properties;
44
 
23723 amit.gupta 45
@Configuration
46
@EnableTransactionManagement
23755 amit.gupta 47
@ComponentScan("com.spice.profitmandi.*")
35393 amit 48
@PropertySource(value = {"classpath:shared-dev.properties", "classpath:META-INF/env.properties"}, ignoreResourceNotFound = true)
23723 amit.gupta 49
public class DBConfig {
50
 
25721 tejbeer 51
	private static final Logger LOGGER = LogManager.getLogger(DBConfig.class);
23723 amit.gupta 52
 
34690 amit.gupta 53
	// Hibernate Property Keys
23755 amit.gupta 54
	private static final String HIBERNATE_DIALECT = "hibernate.dialect";
55
	private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";
56
	private static final String HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
57
	private static final String HIBERNATE_JDBC_BATCH_SIZE = "hibernate.jdbc.batch_size";
23723 amit.gupta 58
 
34690 amit.gupta 59
		// HikariCP Properties
60
	private static final String HIKARI_MAX_POOL_SIZE = "hikari.maximumPoolSize";
61
	private static final String HIKARI_MIN_IDLE = "hikari.minimumIdle";
62
	private static final String HIKARI_IDLE_TIMEOUT = "hikari.idleTimeout";
63
	private static final String HIKARI_MAX_LIFETIME = "hikari.maxLifetime";
64
	private static final String HIKARI_CONNECTION_TIMEOUT = "hikari.connectionTimeout";
23723 amit.gupta 65
 
66
 
34690 amit.gupta 67
	// Injected DB Properties
23723 amit.gupta 68
	@Value("${hibernate.driver.class}")
69
	private String hibernateDriverClass;
70
 
71
	@Value("${hibernate.url}")
72
	private String hibernateUrl;
73
 
74
	@Value("${hibernate.user.name}")
75
	private String hibernateUserName;
76
 
77
	@Value("${hibernate.password}")
78
	private String hibernatePassword;
79
 
80
	@Value("${hibernate.dialect}")
81
	private String hibernateDialect;
82
 
83
	@Value("${hibernate.show_sql}")
84
	private String hibernateShowSql;
85
 
86
	@Value("${hibernate.format_sql}")
87
	private String hibernateFormatSql;
88
 
89
	@Value("${hibernate.jdbc.batch_size}")
90
	private String hibernateBatchSize;
91
 
35828 amit 92
	@Value("${hibernate.order_inserts:true}")
93
	private String hibernateOrderInserts;
94
 
95
	@Value("${hibernate.order_updates:true}")
96
	private String hibernateOrderUpdates;
97
 
34690 amit.gupta 98
	// Mongo Config
23738 amit.gupta 99
	@Value("${mongo.host}")
100
	private String mongoHost;
23723 amit.gupta 101
 
23738 amit.gupta 102
	@Value("${content.mongo.host}")
103
	private String contentMongoHost;
25721 tejbeer 104
 
34690 amit.gupta 105
	@Autowired
106
	private Environment env;
107
 
108
	/**
109
	 * Primary DataSource using DriverManager (can be replaced with HikariDataSource)
110
	 */
23898 amit.gupta 111
	@Primary
35393 amit 112
	@Bean(name = "dataSource", destroyMethod = "close")
113
	public HikariDataSource dataSource() {
34690 amit.gupta 114
		HikariConfig config = new HikariConfig();
115
		config.setDriverClassName(hibernateDriverClass);
116
		config.setJdbcUrl(hibernateUrl);
117
		config.setUsername(hibernateUserName);
118
		config.setPassword(hibernatePassword);
119
 
120
		config.setMaximumPoolSize(Integer.parseInt(env.getProperty(HIKARI_MAX_POOL_SIZE, "20")));
121
		config.setMinimumIdle(Integer.parseInt(env.getProperty(HIKARI_MIN_IDLE, "2")));
122
		config.setIdleTimeout(Long.parseLong(env.getProperty(HIKARI_IDLE_TIMEOUT, "30000")));
123
		config.setMaxLifetime(Long.parseLong(env.getProperty(HIKARI_MAX_LIFETIME, "1800000")));
124
		config.setConnectionTimeout(Long.parseLong(env.getProperty(HIKARI_CONNECTION_TIMEOUT, "30000")));
125
 
126
		config.setPoolName("HikariPool");
35586 amit 127
		config.setAutoCommit(false);
34690 amit.gupta 128
 
129
 
130
		HikariDataSource dataSource = new HikariDataSource(config);
131
		LOGGER.info("HikariDataSource initialized with JDBC URL {}", hibernateUrl);
23723 amit.gupta 132
		return dataSource;
133
	}
25721 tejbeer 134
 
34690 amit.gupta 135
	/**
136
	 * Configure Hibernate properties
137
	 */
24433 amit.gupta 138
	@Bean
23723 amit.gupta 139
	public Properties getHibernateProperties() {
140
		Properties dbProperties = new Properties();
141
		dbProperties.put(HIBERNATE_DIALECT, hibernateDialect);
142
		dbProperties.put(HIBERNATE_SHOW_SQL, hibernateShowSql);
143
		dbProperties.put(HIBERNATE_FORMAT_SQL, hibernateFormatSql);
144
		dbProperties.put(HIBERNATE_JDBC_BATCH_SIZE, hibernateBatchSize);
35828 amit 145
		dbProperties.put("hibernate.order_inserts", hibernateOrderInserts);
146
		dbProperties.put("hibernate.order_updates", hibernateOrderUpdates);
23723 amit.gupta 147
		return dbProperties;
148
	}
25721 tejbeer 149
 
34690 amit.gupta 150
	/**
151
	 * Configure Hibernate SessionFactory
152
	 */
23898 amit.gupta 153
	@Primary
34690 amit.gupta 154
	@Bean(name = "sessionFactory")
23723 amit.gupta 155
	@Autowired
156
	public SessionFactory getSessionFactory(DataSource dataSource) {
157
		LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
158
		sessionBuilder.addProperties(getHibernateProperties());
159
		sessionBuilder.scanPackages("com.spice.profitmandi.dao.*");
34690 amit.gupta 160
		LOGGER.info("SessionFactory created");
23723 amit.gupta 161
		return sessionBuilder.buildSessionFactory();
162
	}
25721 tejbeer 163
 
34690 amit.gupta 164
	/**
165
	 * Transaction Manager
166
	 */
23898 amit.gupta 167
	@Primary
34690 amit.gupta 168
	@Bean(name = "transactionManager")
23723 amit.gupta 169
	@Autowired
170
	public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
171
		HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
34690 amit.gupta 172
		LOGGER.info("TransactionManager created");
23723 amit.gupta 173
		return transactionManager;
174
	}
25721 tejbeer 175
 
34690 amit.gupta 176
	/**
177
	 * ObjectMapper Bean with Java 8 Time module config
178
	 */
23738 amit.gupta 179
	@Bean
34690 amit.gupta 180
	public ObjectMapper objectMapper() {
181
		DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
182
				.parseCaseInsensitive()
183
				.append(DateTimeFormatter.ISO_LOCAL_DATE)
184
				.optionalStart().appendLiteral('T').optionalEnd()
185
				.appendLiteral(' ')
186
				.append(DateTimeFormatter.ISO_LOCAL_TIME)
187
				.toFormatter();
188
 
189
		DateTimeFormatter standardFormatter = new DateTimeFormatterBuilder()
190
				.parseCaseInsensitive()
191
				.append(DateTimeFormatter.ISO_LOCAL_DATE)
192
				.appendLiteral('T')
193
				.append(DateTimeFormatter.ISO_LOCAL_TIME)
194
				.toFormatter();
195
 
196
		JavaTimeModule javaTimeModule = new JavaTimeModule();
197
		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(standardFormatter));
198
		javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
199
		javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
200
		javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE));
201
 
202
		ObjectMapper mapper = new ObjectMapper()
203
				.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
204
				.registerModule(new ParameterNamesModule())
205
				.registerModule(new Jdk8Module())
206
				.registerModule(javaTimeModule);
207
 
208
		LOGGER.info("ObjectMapper configured");
209
		return mapper;
210
	}
211
 
212
	/**
213
	 * Mongo Client Bean
214
	 */
35393 amit 215
	@Bean(destroyMethod = "close")
23738 amit.gupta 216
	public Mongo mongoClient(SessionFactory sessionFactory) {
217
		return new Mongo(mongoHost, contentMongoHost);
218
	}
25721 tejbeer 219
 
34690 amit.gupta 220
	/**
221
	 * Gson Bean for LocalDate and LocalDateTime
222
	 */
25721 tejbeer 223
	@Bean(name = "gson")
224
	public Gson gson() {
34690 amit.gupta 225
		Gson gson = new GsonBuilder()
226
				.serializeNulls()
29838 tejbeer 227
				.registerTypeAdapter(LocalDate.class, new LocalDateJsonConverter())
34690 amit.gupta 228
				.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonConverter())
229
				.create();
230
		LOGGER.info("Gson configured");
25721 tejbeer 231
		return gson;
232
	}
35393 amit 233
 
234
	/**
235
	 * Cleanup method to prevent memory leaks on shutdown.
236
	 * Deregisters JDBC drivers and stops MySQL cleanup thread.
237
	 */
238
	@PreDestroy
239
	public void cleanup() {
240
		LOGGER.info("DBConfig cleanup started...");
241
 
242
		// Stop MySQL AbandonedConnectionCleanupThread
243
		try {
244
			AbandonedConnectionCleanupThread.checkedShutdown();
245
			LOGGER.info("MySQL AbandonedConnectionCleanupThread stopped");
246
		} catch (Exception e) {
247
			LOGGER.error("Error stopping MySQL cleanup thread", e);
248
		}
249
 
250
		// Deregister JDBC drivers loaded by this webapp's classloader
251
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
252
		Enumeration<Driver> drivers = DriverManager.getDrivers();
253
		while (drivers.hasMoreElements()) {
254
			Driver driver = drivers.nextElement();
255
			if (driver.getClass().getClassLoader() == cl) {
256
				try {
257
					DriverManager.deregisterDriver(driver);
258
					LOGGER.info("Deregistered JDBC driver: {}", driver);
259
				} catch (SQLException e) {
260
					LOGGER.error("Error deregistering JDBC driver {}", driver, e);
261
				}
262
			}
263
		}
264
 
265
		LOGGER.info("DBConfig cleanup completed");
266
	}
23723 amit.gupta 267
}