diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/FeignTenantConfiguration.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/FeignTenantConfiguration.java new file mode 100644 index 00000000..341730e4 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/FeignTenantConfiguration.java @@ -0,0 +1,29 @@ +package com.bonus.core.tenant; + +import com.bonus.core.common.utils.TenantContextHolder; +import feign.RequestInterceptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; + +@AutoConfiguration +public class FeignTenantConfiguration { + private static final Logger log = LoggerFactory.getLogger(FeignTenantConfiguration.class); + private final TenantConfigProperties tenantConfigProperties; + + @Bean + public RequestInterceptor feignTenantIdFiller() { + return (template) -> { + if (TenantContextHolder.getTenantId() == null) { + log.warn("Feign tenant fill: there's no tenantId in threadLocal, fallback to null!"); + } else { + template.header(this.tenantConfigProperties.getCarrierName(), new String[]{TenantContextHolder.getTenantId().toString()}); + } + }; + } + + public FeignTenantConfiguration(final TenantConfigProperties tenantConfigProperties) { + this.tenantConfigProperties = tenantConfigProperties; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantConfigProperties.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantConfigProperties.java new file mode 100644 index 00000000..61b2a7e3 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantConfigProperties.java @@ -0,0 +1,33 @@ +package com.bonus.core.tenant; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Component; + +@Component +@RefreshScope +@ConfigurationProperties( + prefix = "tenant" +) +public class TenantConfigProperties { + private String mdc = "x-tenant"; + private String carrierName = "X-Tenant"; + + public String getMdc() { + return this.mdc; + } + + public String getCarrierName() { + return this.carrierName; + } + + public void setMdc(final String mdc) { + this.mdc = mdc; + } + + public void setCarrierName(final String carrierName) { + this.carrierName = carrierName; + } + + +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantContextHolderFilter.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantContextHolderFilter.java new file mode 100644 index 00000000..c8dfea70 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantContextHolderFilter.java @@ -0,0 +1,65 @@ + package com.bonus.core.tenant; + +import cn.hutool.core.text.CharSequenceUtil; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.bonus.core.common.utils.TenantContextHolder; +import java.io.IOException; + +import com.bonus.core.data.dataset.rule.RoutingRule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + + @Component +@Order(Integer.MIN_VALUE) +public class TenantContextHolderFilter extends GenericFilterBean { + private static final Logger log = LoggerFactory.getLogger(TenantContextHolderFilter.class); + private final TenantConfigProperties tenantConfigProperties; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException { + RoutingRule.reset(); + + try { + String tenantId = null; + if (servletRequest instanceof HttpServletRequest) { + tenantId = ((HttpServletRequest)servletRequest).getHeader(this.tenantConfigProperties.getCarrierName()); + } + + if (StringUtils.isBlank(tenantId)) { + tenantId = servletRequest.getParameter(this.tenantConfigProperties.getCarrierName()); + } + + if (CharSequenceUtil.isBlank(tenantId)) { + TenantContextHolder.setTenantId((Long)null); + } else { + if (!tenantId.matches("^\\d+$")) { + return; + } + + TenantContextHolder.setTenantId(Long.parseLong(tenantId)); + } + + log.trace("retrieved tenant from request args:{}", TenantContextHolder.getTenantId()); + MDC.put(this.tenantConfigProperties.getMdc(), TenantContextHolder.getTenantId() == null ? null : String.valueOf(TenantContextHolder.getTenantId())); + filterChain.doFilter(servletRequest, servletResponse); + } finally { + RoutingRule.reset(); + TenantContextHolder.clear(); + MDC.remove(this.tenantConfigProperties.getMdc()); + } + } + + public TenantContextHolderFilter(final TenantConfigProperties tenantConfigProperties) { + this.tenantConfigProperties = tenantConfigProperties; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantLoader.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantLoader.java new file mode 100644 index 00000000..bdeab057 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/core/tenant/TenantLoader.java @@ -0,0 +1,7 @@ +package com.bonus.core.tenant; + +import java.util.Set; + +public interface TenantLoader { + Set listTenant(); +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/bootstrap.yml b/bonus-modules/bonus-smart-canteen/src/main/resources/bootstrap.yml index 68a0ce63..13411ba7 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/resources/bootstrap.yml +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/bootstrap.yml @@ -43,4 +43,9 @@ oss: useToken: ${OSS_USE_TOKEN:false} region: ${OSS_REGION:} path-style-access: ${OSS_PATH_STYLE:true} - useHttp: ${OSS_USE_HTTP:false} \ No newline at end of file + useHttp: ${OSS_USE_HTTP:false} + +tenant: + carrier-name: MERCHANT-ID + schema-prefix: ${TENANT_SCHEMA_PREFIX:} + schema-suffix: ${TENANT_SCHEMA_SUFFIX:} \ No newline at end of file