Guest User

Untitled

a guest
Oct 9th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. @Component
  2.  
  3. public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {
  4.  
  5. @Override
  6.  
  7. public String resolveCurrentTenantIdentifier() {
  8.  
  9. String tenantId = TenantContext.getCurrentTenant();
  10.  
  11. if (tenantId != null) {
  12.  
  13. return tenantId;
  14.  
  15. }
  16.  
  17. return DEFAULT_TENANT_ID;
  18.  
  19. }
  20.  
  21. @Override
  22.  
  23. public boolean validateExistingCurrentSessions() {
  24.  
  25. return true;
  26.  
  27. }
  28.  
  29. }
  30.  
  31. @Component
  32. @Profile("prod")
  33. public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
  34. private static final long serialVersionUID = 3193007611085791247L;
  35. private Logger log = LogManager.getLogger();
  36.  
  37. private Map<String, HikariDataSource> dataSourceMap = new ConcurrentHashMap<String, HikariDataSource>();
  38.  
  39. @Autowired
  40. private TenantRestClient tenantRestClient;
  41.  
  42. @Autowired
  43. private PasswordEncrypt passwordEncrypt;
  44.  
  45. @Override
  46. public void releaseAnyConnection(Connection connection) throws SQLException {
  47. connection.close();
  48. }
  49.  
  50. @Override
  51. public Connection getAnyConnection() throws SQLException {
  52. Connection connection = getDataSource(TenantIdResolver.TENANT_DEFAULT).getConnection();
  53. return connection;
  54.  
  55. }
  56.  
  57. @Override
  58. public Connection getConnection(String tenantId) throws SQLException {
  59. Connection connection = getDataSource(tenantId).getConnection();
  60. return connection;
  61. }
  62.  
  63. @Override
  64. public void releaseConnection(String tenantId, Connection connection) throws SQLException {
  65. log.info("releaseConnection " + tenantId);
  66. connection.close();
  67. }
  68.  
  69. @Override
  70. public boolean supportsAggressiveRelease() {
  71. return false;
  72. }
  73.  
  74. @Override
  75. public boolean isUnwrappableAs(Class unwrapType) {
  76. return false;
  77. }
  78.  
  79. @Override
  80. public <T> T unwrap(Class<T> unwrapType) {
  81. return null;
  82. }
  83.  
  84. public HikariDataSource getDataSource(@NotNull String tentantId) throws SQLException {
  85. if (dataSourceMap.containsKey(tentantId)) {
  86. return dataSourceMap.get(tentantId);
  87. } else {
  88. HikariDataSource dataSource = createDataSource(tentantId);
  89. dataSourceMap.put(tentantId, dataSource);
  90. return dataSource;
  91. }
  92. }
  93.  
  94. public HikariDataSource createDataSource(String tenantId) throws SQLException {
  95. log.info("Create Datasource for tenant {}", tenantId);
  96. try {
  97. Database database = tenantRestClient.getDatabase(tenantId);
  98. DatabaseInstance databaseInstance = tenantRestClient.getDatabaseInstance(tenantId);
  99. if (database != null && databaseInstance != null) {
  100. HikariConfig hikari = new HikariConfig();
  101. String driver = "";
  102. String options = "";
  103. switch (databaseInstance.getType()) {
  104. case MYSQL:
  105. driver = "jdbc:mysql://";
  106. options = "?useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF-8&useSSL=false";
  107. break;
  108.  
  109. default:
  110. driver = "jdbc:mysql://";
  111. options = "?useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF-8&useSSL=false";
  112. }
  113.  
  114. hikari.setJdbcUrl(driver + databaseInstance.getHost() + ":" + databaseInstance.getPort() + "/" + database.getName() + options);
  115. hikari.setUsername(database.getUsername());
  116. hikari.setPassword(passwordEncrypt.decryptPassword(database.getPassword()));
  117.  
  118. // MySQL optimizations, see
  119. // https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
  120. hikari.addDataSourceProperty("cachePrepStmts", true);
  121. hikari.addDataSourceProperty("prepStmtCacheSize", "250");
  122. hikari.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
  123. hikari.addDataSourceProperty("useServerPrepStmts", "true");
  124. hikari.addDataSourceProperty("useLocalSessionState", "true");
  125. hikari.addDataSourceProperty("useLocalTransactionState", "true");
  126. hikari.addDataSourceProperty("rewriteBatchedStatements", "true");
  127. hikari.addDataSourceProperty("cacheResultSetMetadata", "true");
  128. hikari.addDataSourceProperty("cacheServerConfiguration", "true");
  129. hikari.addDataSourceProperty("elideSetAutoCommits", "true");
  130. hikari.addDataSourceProperty("maintainTimeStats", "false");
  131. hikari.setMinimumIdle(3);
  132. hikari.setMaximumPoolSize(5);
  133.  
  134. hikari.setIdleTimeout(30000);
  135. hikari.setPoolName("JPAHikari_" + tenantId);
  136. // mysql wait_timeout 600seconds
  137. hikari.setMaxLifetime(580000);
  138. hikari.setLeakDetectionThreshold(60 * 1000);
  139.  
  140. HikariDataSource dataSource = new HikariDataSource(hikari);
  141.  
  142.  
  143. return dataSource;
  144.  
  145. } else {
  146. throw new SQLException(String.format("DB not found for tenant %s!", tenantId));
  147. }
  148. } catch (Exception e) {
  149. throw new SQLException(e.getMessage());
  150. }
  151. }
  152.  
  153. }
  154.  
  155. @Configuration
  156. @Profile("prod")
  157. public class HibernateConfig {
  158.  
  159. @Autowired
  160. private JpaProperties jpaProperties;
  161.  
  162. @Bean
  163. public JpaVendorAdapter jpaVendorAdapter() {
  164. return new HibernateJpaVendorAdapter();
  165. }
  166.  
  167. @Bean
  168. public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
  169. MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
  170. CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {
  171. Map<String, Object> properties = new HashMap<>();
  172. properties.putAll(jpaProperties.getHibernateProperties(new HibernateSettings()));
  173. properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
  174. properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);
  175. properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);
  176. LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
  177. em.setDataSource(dataSource);
  178. em.setPackagesToScan("com.server");
  179. em.setJpaVendorAdapter(jpaVendorAdapter());
  180. em.setJpaPropertyMap(properties);
  181.  
  182. return em;
  183. }
  184.  
  185. }
  186.  
  187. spring.datasource.url=jdbc:mysql://url:3306/empty?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false
  188. spring.datasource.username=empty
  189. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  190. spring.datasource.password=empty
  191. spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
  192. spring.jpa.hibernate.ddl-auto: validate
  193. spring.jpa.hibernate.naming.physical- strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  194. spring.jpa.show-sql: false
Add Comment
Please, Sign In to add comment