Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Component
- public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {
- @Override
- public String resolveCurrentTenantIdentifier() {
- String tenantId = TenantContext.getCurrentTenant();
- if (tenantId != null) {
- return tenantId;
- }
- return DEFAULT_TENANT_ID;
- }
- @Override
- public boolean validateExistingCurrentSessions() {
- return true;
- }
- }
- @Component
- @Profile("prod")
- public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
- private static final long serialVersionUID = 3193007611085791247L;
- private Logger log = LogManager.getLogger();
- private Map<String, HikariDataSource> dataSourceMap = new ConcurrentHashMap<String, HikariDataSource>();
- @Autowired
- private TenantRestClient tenantRestClient;
- @Autowired
- private PasswordEncrypt passwordEncrypt;
- @Override
- public void releaseAnyConnection(Connection connection) throws SQLException {
- connection.close();
- }
- @Override
- public Connection getAnyConnection() throws SQLException {
- Connection connection = getDataSource(TenantIdResolver.TENANT_DEFAULT).getConnection();
- return connection;
- }
- @Override
- public Connection getConnection(String tenantId) throws SQLException {
- Connection connection = getDataSource(tenantId).getConnection();
- return connection;
- }
- @Override
- public void releaseConnection(String tenantId, Connection connection) throws SQLException {
- log.info("releaseConnection " + tenantId);
- connection.close();
- }
- @Override
- public boolean supportsAggressiveRelease() {
- return false;
- }
- @Override
- public boolean isUnwrappableAs(Class unwrapType) {
- return false;
- }
- @Override
- public <T> T unwrap(Class<T> unwrapType) {
- return null;
- }
- public HikariDataSource getDataSource(@NotNull String tentantId) throws SQLException {
- if (dataSourceMap.containsKey(tentantId)) {
- return dataSourceMap.get(tentantId);
- } else {
- HikariDataSource dataSource = createDataSource(tentantId);
- dataSourceMap.put(tentantId, dataSource);
- return dataSource;
- }
- }
- public HikariDataSource createDataSource(String tenantId) throws SQLException {
- log.info("Create Datasource for tenant {}", tenantId);
- try {
- Database database = tenantRestClient.getDatabase(tenantId);
- DatabaseInstance databaseInstance = tenantRestClient.getDatabaseInstance(tenantId);
- if (database != null && databaseInstance != null) {
- HikariConfig hikari = new HikariConfig();
- String driver = "";
- String options = "";
- switch (databaseInstance.getType()) {
- case MYSQL:
- driver = "jdbc:mysql://";
- options = "?useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF-8&useSSL=false";
- break;
- default:
- driver = "jdbc:mysql://";
- options = "?useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF-8&useSSL=false";
- }
- hikari.setJdbcUrl(driver + databaseInstance.getHost() + ":" + databaseInstance.getPort() + "/" + database.getName() + options);
- hikari.setUsername(database.getUsername());
- hikari.setPassword(passwordEncrypt.decryptPassword(database.getPassword()));
- // MySQL optimizations, see
- // https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
- hikari.addDataSourceProperty("cachePrepStmts", true);
- hikari.addDataSourceProperty("prepStmtCacheSize", "250");
- hikari.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
- hikari.addDataSourceProperty("useServerPrepStmts", "true");
- hikari.addDataSourceProperty("useLocalSessionState", "true");
- hikari.addDataSourceProperty("useLocalTransactionState", "true");
- hikari.addDataSourceProperty("rewriteBatchedStatements", "true");
- hikari.addDataSourceProperty("cacheResultSetMetadata", "true");
- hikari.addDataSourceProperty("cacheServerConfiguration", "true");
- hikari.addDataSourceProperty("elideSetAutoCommits", "true");
- hikari.addDataSourceProperty("maintainTimeStats", "false");
- hikari.setMinimumIdle(3);
- hikari.setMaximumPoolSize(5);
- hikari.setIdleTimeout(30000);
- hikari.setPoolName("JPAHikari_" + tenantId);
- // mysql wait_timeout 600seconds
- hikari.setMaxLifetime(580000);
- hikari.setLeakDetectionThreshold(60 * 1000);
- HikariDataSource dataSource = new HikariDataSource(hikari);
- return dataSource;
- } else {
- throw new SQLException(String.format("DB not found for tenant %s!", tenantId));
- }
- } catch (Exception e) {
- throw new SQLException(e.getMessage());
- }
- }
- }
- @Configuration
- @Profile("prod")
- public class HibernateConfig {
- @Autowired
- private JpaProperties jpaProperties;
- @Bean
- public JpaVendorAdapter jpaVendorAdapter() {
- return new HibernateJpaVendorAdapter();
- }
- @Bean
- public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
- MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
- CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {
- Map<String, Object> properties = new HashMap<>();
- properties.putAll(jpaProperties.getHibernateProperties(new HibernateSettings()));
- properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
- properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);
- properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);
- LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
- em.setDataSource(dataSource);
- em.setPackagesToScan("com.server");
- em.setJpaVendorAdapter(jpaVendorAdapter());
- em.setJpaPropertyMap(properties);
- return em;
- }
- }
- spring.datasource.url=jdbc:mysql://url:3306/empty?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false
- spring.datasource.username=empty
- spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
- spring.datasource.password=empty
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
- spring.jpa.hibernate.ddl-auto: validate
- spring.jpa.hibernate.naming.physical- strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
- spring.jpa.show-sql: false
Add Comment
Please, Sign In to add comment