重构 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