重构 multi-tenant library
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantConnectionProviderImpl.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantConnectionProviderImpl.java
new file mode 100644
index 0000000..737cba0
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantConnectionProviderImpl.java
@@ -0,0 +1,79 @@
+package com.supwisdom.multitenant.datasource;
+
+import com.supwisdom.multitenant.TenantContextHolder;
+import com.supwisdom.multitenant.TenantDetails;
+import lombok.extern.slf4j.Slf4j;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Created by shuwei on 2018/12/4.
+ */
+@Slf4j
+@Component
+public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
+ private final DataSource dataSource;
+
+ private final MultiTenantDataSourceProvider dsProvider;
+
+ public MultiTenantConnectionProviderImpl(DataSource dataSource,
+ MultiTenantDataSourceProvider provider) {
+ this.dataSource = dataSource;
+ this.dsProvider = provider;
+ }
+
+ @Override
+ public Connection getAnyConnection() throws SQLException {
+ return dataSource.getConnection();
+ }
+
+ @Override
+ public void releaseAnyConnection(Connection connection) throws SQLException {
+ connection.close();
+ }
+
+ @Override
+ public Connection getConnection(String ti) throws SQLException {
+ TenantDetails tenant = TenantContextHolder.getContext().getTenant();
+ final Connection connection = getAnyConnection();
+ try {
+ if (tenant != null) {
+ log.debug("postgresql set search path to <" + tenant.getDbSchema() + ">");
+ connection.createStatement().execute(dsProvider.getTenantSQL(tenant));
+ } else {
+ log.debug("postgresql set search path to public");
+ connection.createStatement().execute(dsProvider.getDefaultSQL());
+ }
+ } catch (SQLException e) {
+ assert tenant != null;
+ throw new HibernateException("Problem setting schema to " + tenant.toString(), e);
+ }
+ return connection;
+ }
+
+ @Override
+ public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
+ connection.close();
+ }
+
+ @Override
+ public boolean supportsAggressiveRelease() {
+ return false;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean isUnwrappableAs(Class unwrapType) {
+ return false;
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> unwrapType) {
+ return null;
+ }
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantDataSourceProvider.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantDataSourceProvider.java
new file mode 100644
index 0000000..394b743
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantDataSourceProvider.java
@@ -0,0 +1,9 @@
+package com.supwisdom.multitenant.datasource;
+
+import com.supwisdom.multitenant.TenantDetails;
+
+public interface MultiTenantDataSourceProvider {
+ String getDefaultSQL();
+
+ String getTenantSQL(TenantDetails details);
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantFactory.java
new file mode 100644
index 0000000..6706bd1
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/MultiTenantFactory.java
@@ -0,0 +1,7 @@
+package com.supwisdom.multitenant.datasource;
+
+import com.supwisdom.multitenant.datasource.beans.TenantProps;
+
+public interface MultiTenantFactory {
+ TenantProps createMultiTenant();
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/beans/TenantProps.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/beans/TenantProps.java
new file mode 100644
index 0000000..5e0b6da
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/beans/TenantProps.java
@@ -0,0 +1,5 @@
+package com.supwisdom.multitenant.datasource.beans;
+
+public class TenantProps {
+ private String schema;
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MultiTenantDataSourceAutoConfiguration.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MultiTenantDataSourceAutoConfiguration.java
new file mode 100644
index 0000000..db0c5f7
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MultiTenantDataSourceAutoConfiguration.java
@@ -0,0 +1,22 @@
+package com.supwisdom.multitenant.datasource.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.type.AnnotationMetadata;
+
+@Configuration
+public class MultiTenantDataSourceAutoConfiguration implements ImportBeanDefinitionRegistrar {
+
+ @Value("${spring.jpa.database-platform:all}")
+ private String datasourcePlatform;
+
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+// GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
+// beanDefinition.setBeanClass();
+// registry.registerBeanDefinition();
+ }
+
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MutliTenantHibernateConfig.java
similarity index 84%
rename from multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MutliTenantHibernateConfig.java
index 3365265..87be5f6 100644
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/config/MutliTenantHibernateConfig.java
@@ -1,12 +1,14 @@
-package com.supwisdom.payapi.multitenant.config;
+package com.supwisdom.multitenant.datasource.config;
+import com.supwisdom.multitenant.MultiTenantAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.cfg.Environment;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
@@ -21,15 +23,16 @@
import java.util.Map;
@Configuration
+@ConditionalOnBean({MultiTenantAutoConfiguration.class})
@Slf4j
-public class HibernateConfig {
+public class MutliTenantHibernateConfig {
private final JpaProperties jpaProperties;
private final HibernateProperties hibernateProperties;
- public HibernateConfig(@Autowired JpaProperties jpaProperties,
- HibernateProperties hibernateProperties) {
+ public MutliTenantHibernateConfig(@Autowired JpaProperties jpaProperties,
+ HibernateProperties hibernateProperties) {
this.jpaProperties = jpaProperties;
this.hibernateProperties = hibernateProperties;
}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/impl/PostgresDataSourceProvider.java b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/impl/PostgresDataSourceProvider.java
new file mode 100644
index 0000000..19305ef
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/multitenant/datasource/impl/PostgresDataSourceProvider.java
@@ -0,0 +1,25 @@
+package com.supwisdom.multitenant.datasource.impl;
+
+import com.supwisdom.multitenant.TenantDetails;
+import com.supwisdom.multitenant.datasource.MultiTenantDataSourceProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+@Configuration
+@ConditionalOnExpression("${spring.jpa.database-platform:postgresql}")
+public class PostgresDataSourceProvider implements MultiTenantDataSourceProvider {
+ @Override
+ public String getTenantSQL(TenantDetails details) {
+ if (details == null || details.getDbSchema() == null
+ || StringUtils.isEmpty(details.getDbSchema())) {
+ return getDefaultSQL();
+ }
+ return String.format("set search_path \"%s\", public; ", details.getDbSchema());
+ }
+
+ @Override
+ public String getDefaultSQL() {
+ return "set search_path public;";
+ }
+}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java
deleted file mode 100644
index 898e647..0000000
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.supwisdom.payapi.multitenant;
-
-public class DefaultMultiTenantFactory implements MultiTenantFactory {
-}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java
deleted file mode 100644
index 1c829f8..0000000
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.supwisdom.payapi.multitenant;
-
-public interface MultiTenantFactory {
-
-}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java
deleted file mode 100644
index 4236e29..0000000
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.supwisdom.payapi.multitenant;
-
-import com.supwisdom.payapi.multitenant.beans.TenantProps;
-
-public class TenantContext {
- private static final ThreadLocal<TenantProps> tenantHolder = new ThreadLocal<>();
-
- public static TenantProps getTenant() {
- return tenantHolder.get();
- }
-
- public static void setTenant(String tenant) {
-
- }
-}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java
deleted file mode 100644
index 6e0abf8..0000000
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.supwisdom.payapi.multitenant.beans;
-
-public class TenantProps {
-}
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java
deleted file mode 100644
index 718d869..0000000
--- a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.supwisdom.payapi.multitenant.config;
-
-import com.supwisdom.payapi.multitenant.DefaultMultiTenantFactory;
-import com.supwisdom.payapi.multitenant.MultiTenantFactory;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class MultiTenantAutoConfiguration {
- @Bean
- @ConditionalOnMissingBean(MultiTenantFactory.class)
- public MultiTenantFactory createFactory() {
- return new DefaultMultiTenantFactory();
- }
-}
diff --git a/multi-tenant-datasource/src/test/java/com/supwisdom/multitenant/datasource/PgDatasourceTest.java b/multi-tenant-datasource/src/test/java/com/supwisdom/multitenant/datasource/PgDatasourceTest.java
new file mode 100644
index 0000000..7aae07a
--- /dev/null
+++ b/multi-tenant-datasource/src/test/java/com/supwisdom/multitenant/datasource/PgDatasourceTest.java
@@ -0,0 +1,17 @@
+package com.supwisdom.multitenant.datasource;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest(classes = {PgDatasourceTest.class},
+ properties = {"multi-tenant.interceptor.httpsession.enabled=true",
+ "multi-tenant.interceptor.httpheader.enabled=true"})
+@TestPropertySource("/test-pg.properties")
+public class PgDatasourceTest {
+
+ @Test
+ public void connectDatasource() {
+
+ }
+}
diff --git a/multi-tenant-datasource/src/test/resources/test-pg.properties b/multi-tenant-datasource/src/test/resources/test-pg.properties
new file mode 100644
index 0000000..3613c3b
--- /dev/null
+++ b/multi-tenant-datasource/src/test/resources/test-pg.properties
@@ -0,0 +1,13 @@
+spring.main.banner-mode=off
+# create and drop tables and sequences, loads import.sql
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
+# Postgresql settings
+spring.datasource.platform=postgresql
+#spring.datasource.url=jdbc:postgresql://ykt.supwisdom.com:15432/payapidev
+spring.datasource.url=jdbc:postgresql://172.28.201.70:15432/payapidev
+spring.datasource.username=payapi
+spring.datasource.password=123456
+spring.datasource.continue-on-error=true
+spring.datasource.initialization-mode=always
\ No newline at end of file