From: Tang Cheng Date: Fri, 20 Dec 2019 15:32:52 +0000 (+0800) Subject: 增加了multi-tenant-core, multi-tenant-datasource ,未完全测试 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=9e4d0e355b1034a0ac4dd03a52248e41193651af;p=epayment%2Ffood_payapi.git 增加了multi-tenant-core, multi-tenant-datasource ,未完全测试 --- diff --git a/build.gradle b/build.gradle index c8474f69..cfaf067e 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,7 @@ subprojects { jerseyClientVersion = '1.19' javaxWSRSVersion = '2.1.1' dom4jVersion = '2.1.1' + javaxServletVersion = '4.0.1' springSocialVersion = '1.1.6.RELEASE' springKafkaVersion = '2.2.8.RELEASE' postgresVersion = '42.2.5' @@ -135,10 +136,14 @@ subprojects { // testImplementation 'org.springframework.boot:spring-boot-test' // implementation "javax.servlet:jstl:1.2" // implementation "taglibs:standard:1.1.2" - testImplementation "org.springframework.boot:spring-boot-starter-test" + + testImplementation("org.springframework.boot:spring-boot-starter-test") { + exclude group: "junit", module: "junit" + } testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}" testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}" + testRuntimeOnly("org.junit.vintage:junit-vintage-engine:${junit_jupiter_version}") testImplementation "io.mockk:mockk:${mockkVersion}" testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}" testImplementation "io.rest-assured:rest-assured:${resetAssuredVersion}" diff --git a/multi-tenant-core/build.gradle b/multi-tenant-core/build.gradle new file mode 100644 index 00000000..b456c6ec --- /dev/null +++ b/multi-tenant-core/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'java' + id 'org.springframework.boot' +} + +dependencies { + implementation "org.springframework:spring-webmvc" + implementation "javax.servlet:javax.servlet-api:${javaxServletVersion}" +} \ No newline at end of file diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java new file mode 100644 index 00000000..3ea1eb15 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java @@ -0,0 +1,40 @@ +package com.supwisdom.multitenant; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; + +public class MultiTenantAutoConfiguration { + + @Configuration + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + @ComponentScan(basePackages = {"com.supwisdom.multitenant"}) + public static class SessionTenantInterceptorAutoConfig { + } + + // @ConditionalOnProperty( +// name = "multi-tenant.interceptor.httpsession.enabled", +// havingValue = "true") +// @Bean +// @Role(BeanDefinition.ROLE_INFRASTRUCTURE) +// @ConditionalOnBean({SessionTenantInterceptorAutoConfig.class}) +// public SessionTenantInterceptorAutoConfig createSessionInterceptor() { +// return new SessionTenantInterceptorAutoConfig(); +// } + + @Configuration + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + @ComponentScan(basePackages = {"com.supwisdom.multitenant"}) + public static class HttpHeaderTenantInterceptorAutoConfig { + } + +// @Bean +// @ConditionalOnProperty( +// name = "multi-tenant.interceptor.httpheader.enabled", +// havingValue = "true") +// @Role(BeanDefinition.ROLE_INFRASTRUCTURE) +// public HttpHeaderTenantInterceptorAutoConfig createHttpHeaderInterceptor() { +// return new HttpHeaderTenantInterceptorAutoConfig(); +// } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java new file mode 100644 index 00000000..0c3bbf22 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java @@ -0,0 +1,9 @@ +package com.supwisdom.multitenant; + +import java.io.Serializable; + +public interface TenantContext extends Serializable { + TenantDetails getTenant(); + + void setTenant(TenantDetails details); +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java new file mode 100644 index 00000000..bb0d51f4 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java @@ -0,0 +1,24 @@ +package com.supwisdom.multitenant; + +import com.supwisdom.multitenant.impl.ThreadLocalTenantContextHolderStrategy; + +public class TenantContextHolder { + private static TenantContextHolderStrategy strategy; + + static { + initialize(); + } + + private static void initialize() { + strategy = new ThreadLocalTenantContextHolderStrategy(); + } + + public static TenantContext getContext() { + return strategy.getContext(); + } + + public static void clearContext() { + strategy.clearContext(); + } + +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java new file mode 100644 index 00000000..300130a8 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java @@ -0,0 +1,11 @@ +package com.supwisdom.multitenant; + +public interface TenantContextHolderStrategy { + TenantContext getContext(); + + void setContext(TenantContext tenant); + + TenantContext createEmptyContext(); + + void clearContext(); +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java new file mode 100644 index 00000000..07372bb5 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java @@ -0,0 +1,46 @@ +package com.supwisdom.multitenant; + +import java.io.Serializable; + +public class TenantDetails implements Serializable { + private String id; + + private String dbSchema; + + private Boolean enabled; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDbSchema() { + return dbSchema; + } + + public void setDbSchema(String dbSchema) { + this.dbSchema = dbSchema; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TenantDetails) { + TenantDetails other = (TenantDetails) obj; + if (getId().equals(other.getId())) { + return true; + } + } + return false; + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java new file mode 100644 index 00000000..3a502495 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java @@ -0,0 +1,7 @@ +package com.supwisdom.multitenant; + +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +public abstract class TenantInterceptor extends HandlerInterceptorAdapter { + +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java new file mode 100644 index 00000000..97f8625a --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java @@ -0,0 +1,13 @@ +package com.supwisdom.multitenant.annotations; + +import com.supwisdom.multitenant.MultiTenantAutoConfiguration; +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(MultiTenantAutoConfiguration.HttpHeaderTenantInterceptorAutoConfig.class) +@Documented +public @interface EnableHttpHeaderTenantInterceptor { +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java new file mode 100644 index 00000000..885140be --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java @@ -0,0 +1,13 @@ +package com.supwisdom.multitenant.annotations; + +import com.supwisdom.multitenant.MultiTenantAutoConfiguration; +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(MultiTenantAutoConfiguration.SessionTenantInterceptorAutoConfig.class) +@Documented +public @interface EnableSessionTenantInterceptor { +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java new file mode 100644 index 00000000..b2d95853 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java @@ -0,0 +1,23 @@ +package com.supwisdom.multitenant.config; + + +import com.supwisdom.multitenant.impl.HttpHeaderTenantInterceptor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@ConditionalOnBean(value = {HttpHeaderTenantInterceptor.class}) +public class HttpHeaderWebMvcConfig implements WebMvcConfigurer { + private final HttpHeaderTenantInterceptor interceptor; + + public HttpHeaderWebMvcConfig(HttpHeaderTenantInterceptor interceptor) { + this.interceptor = interceptor; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(interceptor); + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java new file mode 100644 index 00000000..97c70962 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java @@ -0,0 +1,6 @@ +package com.supwisdom.multitenant.config; + +public final class TenantCoreUtils { + public static final String INTERNAL_TENANT_INTERCEPTOR_BEAN_NAME = "coms.supwisdom.multitenant.interceptor"; + +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java new file mode 100644 index 00000000..4d313909 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java @@ -0,0 +1,20 @@ +package com.supwisdom.multitenant.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("multi-tenant.header") +public class TenantHeaderProperties { + @Value("${key:X-Tenant-Id}") + private String key; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java new file mode 100644 index 00000000..c4dcbb48 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java @@ -0,0 +1,31 @@ +package com.supwisdom.multitenant.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("multi-tenant.jwt") +public class TenantJwtProperties { + @Value("${header:Authentication}") + private String jwtHeader; + + @Value("${schema:Bears}") + private String schema; + + public String getJwtHeader() { + return jwtHeader; + } + + public void setJwtHeader(String jwtHeader) { + this.jwtHeader = jwtHeader; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java new file mode 100644 index 00000000..3d57c62b --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java @@ -0,0 +1,20 @@ +package com.supwisdom.multitenant.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("multi-tenant.session") +public class TenantSessionProperties { + @Value("${name:multi-tenant-id}") + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java new file mode 100644 index 00000000..b8ae3426 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java @@ -0,0 +1,47 @@ +package com.supwisdom.multitenant.impl; + +import com.supwisdom.multitenant.*; +import com.supwisdom.multitenant.config.TenantHeaderProperties; +import com.supwisdom.multitenant.config.TenantJwtProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +@ConditionalOnBean(MultiTenantAutoConfiguration.HttpHeaderTenantInterceptorAutoConfig.class) +public class HttpHeaderTenantInterceptor extends TenantInterceptor { + private final TenantJwtProperties properties; + + private final TenantHeaderProperties headerProperties; + + public HttpHeaderTenantInterceptor(TenantJwtProperties properties, + TenantHeaderProperties headerProperties) { + this.properties = properties; + this.headerProperties = headerProperties; + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String tenant = request.getHeader(headerProperties.getKey()); + if (tenant != null && !StringUtils.isEmpty(tenant)) { + TenantDetails details = new TenantDetails(); + details.setId(tenant); + TenantContextHolder.getContext().setTenant(details); + } + String header = request.getHeader(properties.getJwtHeader()); + if (header.startsWith(properties.getSchema())) { + // parse jwt + } + return super.preHandle(request, response, handler); + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + TenantContextHolder.clearContext(); + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java new file mode 100644 index 00000000..3f9ae2c0 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java @@ -0,0 +1,39 @@ +package com.supwisdom.multitenant.impl; + +import com.supwisdom.multitenant.*; +import com.supwisdom.multitenant.config.TenantSessionProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +@ConditionalOnBean(MultiTenantAutoConfiguration.SessionTenantInterceptorAutoConfig.class) +public class SessionTenantInterceptor extends TenantInterceptor { + private final TenantSessionProperties properties; + + public SessionTenantInterceptor(TenantSessionProperties properties) { + this.properties = properties; + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String tenant = (String) request.getSession().getAttribute(properties.getName()); + if (tenant != null && !StringUtils.isEmpty(tenant)) { + TenantDetails details = new TenantDetails(); + details.setId(tenant); + TenantContextHolder.getContext().setTenant(details); + } + return super.preHandle(request, response, handler); + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + TenantContextHolder.clearContext(); + super.postHandle(request, response, handler, modelAndView); + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java new file mode 100644 index 00000000..39bdae82 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java @@ -0,0 +1,27 @@ +package com.supwisdom.multitenant.impl; + +import com.supwisdom.multitenant.TenantContext; +import com.supwisdom.multitenant.TenantDetails; + +public class TenantContextImpl implements TenantContext { + private TenantDetails details; + + @Override + public TenantDetails getTenant() { + return details; + } + + @Override + public void setTenant(TenantDetails details) { + this.details = details; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TenantContextImpl) { + TenantContextImpl other = (TenantContextImpl) obj; + getTenant().equals(other.getTenant()); + } + return false; + } +} diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java new file mode 100644 index 00000000..fd325ec8 --- /dev/null +++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java @@ -0,0 +1,33 @@ +package com.supwisdom.multitenant.impl; + +import com.supwisdom.multitenant.TenantContext; +import com.supwisdom.multitenant.TenantContextHolderStrategy; + +public class ThreadLocalTenantContextHolderStrategy implements TenantContextHolderStrategy { + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + @Override + public TenantContext getContext() { + TenantContext context = contextHolder.get(); + if (context == null) { + context = createEmptyContext(); + contextHolder.set(context); + } + return context; + } + + @Override + public void setContext(TenantContext tenant) { + contextHolder.set(tenant); + } + + @Override + public void clearContext() { + contextHolder.remove(); + } + + @Override + public TenantContext createEmptyContext() { + return new TenantContextImpl(); + } +} diff --git a/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java b/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java new file mode 100644 index 00000000..4286f3ca --- /dev/null +++ b/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java @@ -0,0 +1,33 @@ +package com.supwisdom.multitenant; + +import com.supwisdom.multitenant.annotations.EnableSessionTenantInterceptor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.TestPropertySource; + +import java.util.Arrays; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +@SpringBootTest(classes = {AutoConfigurationTest.class}) +@EnableSessionTenantInterceptor +@TestPropertySource("/test.properties") +public class AutoConfigurationTest { + + @Autowired + private ApplicationContext appContext; + + @Test + public void testSessionOk() { + String[] beans = appContext.getBeanDefinitionNames(); + Arrays.sort(beans); + for (String bean : beans) { + System.out.println(bean); + } + assertThat(TenantContextHolder.getContext(), notNullValue()); + } + +} diff --git a/multi-tenant-core/src/test/resources/test.properties b/multi-tenant-core/src/test/resources/test.properties new file mode 100644 index 00000000..80c6377d --- /dev/null +++ b/multi-tenant-core/src/test/resources/test.properties @@ -0,0 +1 @@ +debug=true \ No newline at end of file diff --git a/multi-tenant/build.gradle b/multi-tenant-datasource/build.gradle similarity index 95% rename from multi-tenant/build.gradle rename to multi-tenant-datasource/build.gradle index 031c0a33..09ed0146 100644 --- a/multi-tenant/build.gradle +++ b/multi-tenant-datasource/build.gradle @@ -17,6 +17,7 @@ bootJar { } dependencies { + implementation(":multi-tenant-core") implementation "org.springframework.boot:spring-boot-autoconfigure" implementation "commons-beanutils:commons-beanutils:${beanutilsVersion}" implementation "commons-codec:commons-codec:${codecVersion}" diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java similarity index 100% rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java similarity index 100% rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java similarity index 100% rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java similarity index 100% rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java 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/payapi/multitenant/config/HibernateConfig.java new file mode 100644 index 00000000..3365265e --- /dev/null +++ b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java @@ -0,0 +1,65 @@ +package com.supwisdom.payapi.multitenant.config; + + +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.orm.jpa.HibernateProperties; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; + +import javax.sql.DataSource; +import java.util.HashMap; +import java.util.Map; + +@Configuration +@Slf4j +public class HibernateConfig { + + private final JpaProperties jpaProperties; + + private final HibernateProperties hibernateProperties; + + public HibernateConfig(@Autowired JpaProperties jpaProperties, + HibernateProperties hibernateProperties) { + this.jpaProperties = jpaProperties; + this.hibernateProperties = hibernateProperties; + } + + @Bean + public JpaVendorAdapter getJpaVendorAdapter() { + HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); + adapter.setGenerateDdl(true); + return adapter; + } + + @Bean("entityManagerFactory") + public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, + MultiTenantConnectionProvider multiTenantConnectionProvider, + CurrentTenantIdentifierResolver currentTenantIdentifierResolver) { + Map properties = new HashMap<>(); + properties.putAll(hibernateProperties + .determineHibernateProperties(jpaProperties.getProperties(), + new HibernateSettings())); + properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA); + properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider); + properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver); + + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource); + em.setPackagesToScan("com.supwisdom"); + em.setJpaPropertyMap(properties); + em.setJpaVendorAdapter(getJpaVendorAdapter()); + log.info("setup multi-tenant entityManagerFactor"); + return em; + } + +} diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java similarity index 100% rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java diff --git a/settings.gradle b/settings.gradle index 43ea36ed..9ec25d1a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,5 +4,6 @@ include 'payapi-sdk' include 'payapi-common' include 'ynrcc-agent' include 'oauth' -include 'multi-tenant' +include 'multi-tenant-core' +include 'multi-tenant-datasource'