diff --git a/doc/db/2pigxx.sql b/doc/db/2pigxx.sql index 5dbac2092..0106a37f0 100644 --- a/doc/db/2pigxx.sql +++ b/doc/db/2pigxx.sql @@ -276,7 +276,7 @@ CREATE TABLE `sys_route_conf` ( -- Records of `sys_route_conf` -- ---------------------------- BEGIN; -INSERT INTO `sys_route_conf` VALUES ('1', '工作流管理模块', 'pigx-activiti', '[{\"args\": {\"_genkey_0\": \"/act/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-activiti', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:25', '0'), ('2', '认证中心', 'pigx-auth', '[{\"args\": {\"_genkey_0\": \"/auth/**\"}, \"name\": \"Path\"}]', '[{\"args\": {}, \"name\": \"ValidateCodeGatewayFilter\"}, {\"args\": {}, \"name\": \"PasswordDecoderFilter\"}]', 'lb://pigx-auth', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:29', '0'), ('3', '代码生成模块', 'pigx-codegen', '[{\"args\": {\"_genkey_0\": \"/gen/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-codegen', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:32', '0'), ('4', '定时任务模块', 'pigx-daemon', '[{\"args\": {\"_genkey_0\": \"/daemon/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-daemon', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:34', '0'), ('5', '分布式事务模块', 'pigx-tx-manager', '[{\"args\": {\"_genkey_0\": \"/tx/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-tx-manager', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:36', '0'), ('6', '通用权限模块', 'pigx-upms-biz', '[{\"args\": {\"_genkey_0\": \"/admin/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"key-resolver\": \"#{@remoteAddrKeyResolver}\", \"redis-rate-limiter.burstCapacity\": \"20\", \"redis-rate-limiter.replenishRate\": \"10\"}, \"name\": \"RequestRateLimiter\"}, {\"args\": {\"name\": \"default\", \"fallbackUri\": \"forward:/fallback\"}, \"name\": \"Hystrix\"}]', 'lb://pigx-upms-biz', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:39', '0'); +INSERT INTO `sys_route_conf` VALUES ('1', '工作流管理模块', 'pigx-activiti', '[{\"args\": {\"_genkey_0\": \"/act/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-activiti', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:25', '0'), ('2', '认证中心', 'pigx-auth', '[{\"args\": {\"_genkey_0\": \"/auth/**\"}, \"name\": \"Path\"}]', '[{\"args\": {}, \"name\": \"ValidateCodeGatewayFilter\"}, {\"args\": {}, \"name\": \"PasswordDecoderFilter\"}]', 'lb://pigx-auth', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:29', '0'), ('3', '代码生成模块', 'pigx-codegen', '[{\"args\": {\"_genkey_0\": \"/gen/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-codegen', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:32', '0'), ('4', '定时任务模块', 'pigx-daemon', '[{\"args\": {\"_genkey_0\": \"/daemon/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-daemon', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:34', '0'), ('5', '分布式事务模块', 'pigx-tx-manager', '[{\"args\": {\"_genkey_0\": \"/tx/**\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-tx-manager', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:36', '0'), ('6', '通用权限模块', 'pigx-upms-biz', '[{\"args\": {\"_genkey_0\": \"/admin/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"key-resolver\": \"#{@remoteAddrKeyResolver}\", \"redis-rate-limiter.burstCapacity\": \"20\", \"redis-rate-limiter.replenishRate\": \"10\"}, \"name\": \"RequestRateLimiter\"}, {\"args\": {\"name\": \"default\", \"fallbackUri\": \"forward:/fallback\"}, \"name\": \"Hystrix\"}]', 'lb://pigx-upms-biz', '0', '2018-11-28 15:56:10', '2018-11-28 15:56:39', '0'), ('7', '认证中心长连接模块1', 'pigx-auth-ws-1', '[{\"args\": {\"_genkey_0\": \"/auth/ws/info\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-auth', '0', '2019-01-15 19:37:30', '2019-01-16 20:54:47', '0'), ('8', '认证中心长连接模块2', 'pigx-auth-ws-2', '[{\"args\": {\"_genkey_0\": \"/auth/ws/**\"}, \"name\": \"Path\"}]', '[]', 'lb:ws://pigx-auth', '0', '2019-01-15 19:22:39', '2019-01-16 20:54:51', '0'), ('9', '工作流长链接支持1', 'pigx-activiti-ws-1', '[{\"args\": {\"_genkey_0\": \"/act/ws/**\"}, \"name\": \"Path\"}]', '[]', 'lb:ws://pigx-activiti', '0', '2019-01-15 19:22:39', '2019-01-16 20:54:56', '0'), ('10', '工作流长链接支持2', 'pigx-activiti-ws-2', '[{\"args\": {\"_genkey_0\": \"/act/ws/info\"}, \"name\": \"Path\"}]', '[]', 'lb://pigx-activiti', '0', '2019-01-15 19:37:30', '2019-01-16 20:55:07', '0'); COMMIT; -- ---------------------------- diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java index 993d5fb93..2e899ad53 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java @@ -26,6 +26,7 @@ import com.pig4cloud.pigx.common.security.service.PigxClientDetailsService; import com.pig4cloud.pigx.common.security.service.PigxUser; import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -62,7 +63,8 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap private final RedisConnectionFactory redisConnectionFactory; @Override - public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + @SneakyThrows + public void configure(ClientDetailsServiceConfigurer clients) { PigxClientDetailsService clientDetailsService = new PigxClientDetailsService(dataSource); clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT); clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT); @@ -102,9 +104,19 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap return tokenStore; } + /** + * token增强,客户端模式不增强。 + * + * @return TokenEnhancer + */ @Bean public TokenEnhancer tokenEnhancer() { return (accessToken, authentication) -> { + if (SecurityConstants.CLIENT_CREDENTIALS + .equals(authentication.getOAuth2Request().getGrantType())) { + return accessToken; + } + final Map additionalInfo = new HashMap<>(8); PigxUser pigxUser = (PigxUser) authentication.getUserAuthentication().getPrincipal(); additionalInfo.put("user_id", pigxUser.getId()); diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java index 6781dd508..9cc58ea2d 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.pig4cloud.pigx.common.security.handler.MobileLoginSuccessHandler; import com.pig4cloud.pigx.common.security.mobile.MobileSecurityConfigurer; import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService; +import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -59,7 +60,8 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices; @Override - protected void configure(HttpSecurity http) throws Exception { + @SneakyThrows + protected void configure(HttpSecurity http) { http .formLogin() .loginPage("/token/login") @@ -87,7 +89,8 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Bean @Override - public AuthenticationManager authenticationManagerBean() throws Exception { + @SneakyThrows + public AuthenticationManager authenticationManagerBean() { return super.authenticationManagerBean(); } diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java index 22935a874..b1ad0b556 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java @@ -120,4 +120,9 @@ public interface SecurityConstants { */ String RESOURCE_SERVER_CONFIGURER = "resourceServerConfigurerAdapter"; + /** + * 客户端模式 + */ + String CLIENT_CREDENTIALS = "client_credentials"; + } diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/SpringContextHolder.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/SpringContextHolder.java index 0eacf108d..f06f87615 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/SpringContextHolder.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/SpringContextHolder.java @@ -95,7 +95,7 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB * 实现DisposableBean接口, 在Context关闭时清理静态变量. */ @Override - public void destroy() throws Exception { + public void destroy() { SpringContextHolder.clearHolder(); } diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java index ee7cbdcdc..401e7b93b 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java @@ -23,6 +23,7 @@ import cn.hutool.core.codec.Base64; import cn.hutool.core.util.CharsetUtil; import cn.hutool.json.JSONUtil; import com.pig4cloud.pigx.common.core.exception.CheckedException; +import lombok.SneakyThrows; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; @@ -204,7 +205,8 @@ public class WebUtils extends org.springframework.web.util.WebUtils { * * @return */ - public String[] getClientId(ServerHttpRequest request) throws Exception { + @SneakyThrows + public String[] getClientId(ServerHttpRequest request) { String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); if (header == null || !header.startsWith(BASIC_)) { diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java index fd96d9f59..ee34f19ff 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInterceptor.java @@ -29,6 +29,7 @@ import com.pig4cloud.pigx.common.data.enums.DataScopeTypeEnum; import com.pig4cloud.pigx.common.security.service.PigxUser; import com.pig4cloud.pigx.common.security.util.SecurityUtils; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; @@ -58,7 +59,8 @@ public class DataScopeInterceptor extends AbstractSqlParserHandler implements In private final DataSource dataSource; @Override - public Object intercept(Invocation invocation) throws Throwable { + @SneakyThrows + public Object intercept(Invocation invocation) { StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget()); MetaObject metaObject = SystemMetaObject.forObject(statementHandler); this.sqlParser(metaObject); diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java index 9c52e5681..8d1cc1d98 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java @@ -41,18 +41,30 @@ import java.util.List; @MapperScan("com.pig4cloud.pigx.*.mapper") public class MybatisPlusConfig { + /** + * 创建租户维护处理器对象 + * + * @return 处理后的租户维护处理器 + */ + @Bean + @ConditionalOnMissingBean + public PigxTenantHandler pigxTenantHandler() { + return new PigxTenantHandler(); + } + /** * 分页插件 * + * @param tenantHandler 租户处理器 * @return PaginationInterceptor */ @Bean @ConditionalOnMissingBean - public PaginationInterceptor paginationInterceptor() { + public PaginationInterceptor paginationInterceptor(PigxTenantHandler tenantHandler) { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); List sqlParserList = new ArrayList<>(); TenantSqlParser tenantSqlParser = new TenantSqlParser(); - tenantSqlParser.setTenantHandler(new PigxTenantHandler()); + tenantSqlParser.setTenantHandler(tenantHandler); sqlParserList.add(tenantSqlParser); paginationInterceptor.setSqlParserList(sqlParserList); return paginationInterceptor; diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantConfigProperties.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantConfigProperties.java new file mode 100644 index 000000000..899ba9de3 --- /dev/null +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantConfigProperties.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.common.data.tenant; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * 多租户配置 + * + * @author oathsign + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "pigx.tenant") +public class PigxTenantConfigProperties { + + /** + * 维护租户列名称 + */ + private String column="tenant_id"; + + /** + * 多租户的数据表集合 + */ + private List tables = new ArrayList<>(); +} diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java index 82f1d88a8..12729a7b7 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java @@ -17,11 +17,12 @@ package com.pig4cloud.pigx.common.data.tenant; -import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; +import org.springframework.beans.factory.annotation.Autowired; /** * @author lengleng @@ -31,8 +32,8 @@ import net.sf.jsqlparser.expression.LongValue; */ @Slf4j public class PigxTenantHandler implements TenantHandler { - private static final String[] TENANT_TABLES = new String[]{"sys_user", "sys_role", "sys_dept", - "sys_log", "sys_social_details", "sys_dict", "sys_log", "oa_leave_bill"}; + @Autowired + private PigxTenantConfigProperties properties; /** * 获取租户值 @@ -53,7 +54,7 @@ public class PigxTenantHandler implements TenantHandler { */ @Override public String getTenantIdColumn() { - return "tenant_id"; + return properties.getColumn(); } /** @@ -64,6 +65,6 @@ public class PigxTenantHandler implements TenantHandler { */ @Override public boolean doTableFilter(String tableName) { - return !ArrayUtil.contains(TENANT_TABLES, tableName); + return !properties.getTables().contains(tableName); } } diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderFilter.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderFilter.java index 6d2ab51e8..2587decb4 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderFilter.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/TenantContextHolderFilter.java @@ -19,6 +19,7 @@ package com.pig4cloud.pigx.common.data.tenant; import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @@ -26,12 +27,10 @@ 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; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; /** * @author lengleng @@ -43,7 +42,8 @@ import java.io.IOException; public class TenantContextHolderFilter extends GenericFilterBean { @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + @SneakyThrows + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; diff --git a/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories index 5de28f3dc..b31d9ce74 100644 --- a/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories +++ b/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories @@ -2,6 +2,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.pig4cloud.pigx.common.data.cache.RedisTemplateConfig,\ com.pig4cloud.pigx.common.data.cache.RedisCacheManagerConfig,\ com.pig4cloud.pigx.common.data.cache.RedisCacheAutoConfiguration,\ + com.pig4cloud.pigx.common.data.tenant.PigxTenantConfigProperties,\ com.pig4cloud.pigx.common.data.tenant.TenantContextHolderFilter,\ com.pig4cloud.pigx.common.data.tenant.PigxFeignTenantConfiguration,\ com.pig4cloud.pigx.common.data.mybatis.MybatisPlusConfig \ No newline at end of file diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java index e956e57f5..b9b81b5d8 100755 --- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java +++ b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java @@ -31,8 +31,8 @@ import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration; import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler; import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter; import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties; +import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -59,7 +59,8 @@ public abstract class AbstractJobInitialization implements ApplicationContextAwa protected ApplicationContext applicationContext; @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + @SneakyThrows + public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @@ -166,13 +167,13 @@ public abstract class AbstractJobInitialization implements ApplicationContextAwa private LiteJobConfiguration getLiteJobConfiguration(JobTypeConfiguration jobTypeConfiguration, ElasticJobProperties.JobConfiguration jobConfiguration) { //构建Lite作业 return LiteJobConfiguration.newBuilder(Objects.requireNonNull(jobTypeConfiguration)) - .monitorExecution(jobConfiguration.isMonitorExecution()) - .monitorPort(jobConfiguration.getMonitorPort()) - .maxTimeDiffSeconds(jobConfiguration.getMaxTimeDiffSeconds()) - .jobShardingStrategyClass(jobConfiguration.getJobShardingStrategyClass()) - .reconcileIntervalMinutes(jobConfiguration.getReconcileIntervalMinutes()) - .disabled(jobConfiguration.isDisabled()) - .overwrite(jobConfiguration.isOverwrite()).build(); + .monitorExecution(jobConfiguration.isMonitorExecution()) + .monitorPort(jobConfiguration.getMonitorPort()) + .maxTimeDiffSeconds(jobConfiguration.getMaxTimeDiffSeconds()) + .jobShardingStrategyClass(jobConfiguration.getJobShardingStrategyClass()) + .reconcileIntervalMinutes(jobConfiguration.getReconcileIntervalMinutes()) + .disabled(jobConfiguration.isDisabled()) + .overwrite(jobConfiguration.isOverwrite()).build(); } /** @@ -184,11 +185,11 @@ public abstract class AbstractJobInitialization implements ApplicationContextAwa */ protected JobCoreConfiguration getJobCoreConfiguration(String jobName, ElasticJobProperties.JobConfiguration jobConfiguration) { JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder(jobName, jobConfiguration.getCron(), jobConfiguration.getShardingTotalCount()) - .shardingItemParameters(jobConfiguration.getShardingItemParameters()) - .jobParameter(jobConfiguration.getJobParameter()) - .failover(jobConfiguration.isFailover()) - .misfire(jobConfiguration.isMisfire()) - .description(jobConfiguration.getDescription()); + .shardingItemParameters(jobConfiguration.getShardingItemParameters()) + .jobParameter(jobConfiguration.getJobParameter()) + .failover(jobConfiguration.isFailover()) + .misfire(jobConfiguration.isMisfire()) + .description(jobConfiguration.getDescription()); if (StringUtils.isNotBlank(jobConfiguration.getJobExceptionHandler())) { builder.jobProperties(JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), jobConfiguration.getJobExceptionHandler()); } @@ -220,7 +221,7 @@ public abstract class AbstractJobInitialization implements ApplicationContextAwa //注册分布式监听者 AbstractDistributeOnceElasticJobListener distributedListener = registerBean(listener.getDistributedListenerClass(), listener.getDistributedListenerClass(), - AbstractDistributeOnceElasticJobListener.class, listener.getStartedTimeoutMilliseconds(), listener.getCompletedTimeoutMilliseconds()); + AbstractDistributeOnceElasticJobListener.class, listener.getStartedTimeoutMilliseconds(), listener.getCompletedTimeoutMilliseconds()); if (null != distributedListener) { elasticJobListeners.add(distributedListener); } diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java index e60e08513..2452dff1c 100644 --- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java +++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java @@ -24,6 +24,7 @@ import com.pig4cloud.pigx.common.log.aspect.SysLogAspect; import com.pig4cloud.pigx.common.log.event.SysLogListener; import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @@ -47,7 +48,7 @@ public class LogAutoConfiguration { } @Bean - public SysLogAspect sysLogAspect() { - return new SysLogAspect(); + public SysLogAspect sysLogAspect(ApplicationEventPublisher publisher) { + return new SysLogAspect(publisher); } } diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java index ac4d5ac0b..e25d67a8e 100644 --- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java +++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java @@ -19,14 +19,16 @@ package com.pig4cloud.pigx.common.log.aspect; -import com.pig4cloud.pigx.common.core.util.SpringContextHolder; import com.pig4cloud.pigx.common.log.annotation.SysLog; import com.pig4cloud.pigx.common.log.event.SysLogEvent; import com.pig4cloud.pigx.common.log.util.SysLogUtils; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.springframework.context.ApplicationEventPublisher; /** * 操作日志使用spring event异步入库 @@ -35,10 +37,13 @@ import org.aspectj.lang.annotation.Aspect; */ @Slf4j @Aspect +@AllArgsConstructor public class SysLogAspect { + private final ApplicationEventPublisher publisher; + @SneakyThrows @Around("@annotation(sysLog)") - public Object around(ProceedingJoinPoint point, SysLog sysLog) throws Throwable { + public Object around(ProceedingJoinPoint point, SysLog sysLog) { String strClassName = point.getTarget().getClass().getName(); String strMethodName = point.getSignature().getName(); log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName); @@ -50,7 +55,7 @@ public class SysLogAspect { Object obj = point.proceed(); Long endTime = System.currentTimeMillis(); logVo.setTime(endTime - startTime); - SpringContextHolder.publishEvent(new SysLogEvent(logVo)); + publisher.publishEvent(new SysLogEvent(logVo)); return obj; } diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java index 17b7674be..f5a781670 100644 --- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java +++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java @@ -20,15 +20,15 @@ package com.pig4cloud.pigx.common.log.event; import com.pig4cloud.pigx.admin.api.entity.SysLog; -import org.springframework.context.ApplicationEvent; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * @author lengleng * 系统日志事件 */ -public class SysLogEvent extends ApplicationEvent { - - public SysLogEvent(SysLog source) { - super(source); - } +@Getter +@AllArgsConstructor +public class SysLogEvent { + private final SysLog sysLog; } diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java index 8af58281d..bb0c9181f 100644 --- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java +++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java @@ -28,7 +28,6 @@ import org.springframework.context.event.EventListener; import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; - /** * @author lengleng * 异步监听日志事件 @@ -42,7 +41,7 @@ public class SysLogListener { @Order @EventListener(SysLogEvent.class) public void saveSysLog(SysLogEvent event) { - SysLog sysLog = (SysLog) event.getSource(); + SysLog sysLog = event.getSysLog(); remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN); } } diff --git a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/http/MinioEndpoint.java b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/http/MinioEndpoint.java index 1952d6bfd..8345085ae 100755 --- a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/http/MinioEndpoint.java +++ b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/http/MinioEndpoint.java @@ -22,6 +22,7 @@ import com.pig4cloud.common.minio.vo.MinioItem; import com.pig4cloud.common.minio.vo.MinioObject; import io.minio.messages.Bucket; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -48,60 +49,65 @@ public class MinioEndpoint { /** * Bucket Endpoints */ + @SneakyThrows @PostMapping("/bucket/{bucketName}") - public Bucket createBucker(@PathVariable String bucketName) throws Exception { + public Bucket createBucker(@PathVariable String bucketName) { template.createBucket(bucketName); return template.getBucket(bucketName).get(); } + @SneakyThrows @GetMapping("/bucket") - public List getBuckets() throws Exception { + public List getBuckets() { return template.getAllBuckets(); } + @SneakyThrows @GetMapping("/bucket/{bucketName}") - public Bucket getBucket(@PathVariable String bucketName) throws Exception { + public Bucket getBucket(@PathVariable String bucketName) { return template.getBucket(bucketName).orElseThrow(() -> new IllegalArgumentException("Bucket Name not found!")); } + @SneakyThrows @DeleteMapping("/bucket/{bucketName}") @ResponseStatus(HttpStatus.ACCEPTED) - public void deleteBucket(@PathVariable String bucketName) throws Exception { - + public void deleteBucket(@PathVariable String bucketName) { template.removeBucket(bucketName); } /** * Object Endpoints */ - + @SneakyThrows @PostMapping("/object/{bucketName}") - public MinioObject createObject(@RequestBody MultipartFile object, @PathVariable String bucketName) throws Exception { + public MinioObject createObject(@RequestBody MultipartFile object, @PathVariable String bucketName) { String name = object.getOriginalFilename(); template.putObject(bucketName, name, object.getInputStream(), object.getSize(), object.getContentType()); return new MinioObject(template.getObjectInfo(bucketName, name)); } + @SneakyThrows @PostMapping("/object/{bucketName}/{objectName}") - public MinioObject createObject(@RequestBody MultipartFile object, @PathVariable String bucketName, @PathVariable String objectName) throws Exception { + public MinioObject createObject(@RequestBody MultipartFile object, @PathVariable String bucketName, @PathVariable String objectName) { template.putObject(bucketName, objectName, object.getInputStream(), object.getSize(), object.getContentType()); return new MinioObject(template.getObjectInfo(bucketName, objectName)); } - + @SneakyThrows @GetMapping("/object/{bucketName}/{objectName}") - public List filterObject(@PathVariable String bucketName, @PathVariable String objectName) throws Exception { + public List filterObject(@PathVariable String bucketName, @PathVariable String objectName) { return template.getAllObjectsByPrefix(bucketName, objectName, true); } + @SneakyThrows @GetMapping("/object/{bucketName}/{objectName}/{expires}") - public Map getObject(@PathVariable String bucketName, @PathVariable String objectName, @PathVariable Integer expires) throws Exception { + public Map getObject(@PathVariable String bucketName, @PathVariable String objectName, @PathVariable Integer expires) { Map responseBody = new HashMap<>(8); // Put Object info responseBody.put("bucket", bucketName); @@ -111,9 +117,10 @@ public class MinioEndpoint { return responseBody; } - @DeleteMapping("/object/{bucketName}/{objectName}/") + @SneakyThrows @ResponseStatus(HttpStatus.ACCEPTED) - public void deleteObject(@PathVariable String bucketName, @PathVariable String objectName) throws Exception { + @DeleteMapping("/object/{bucketName}/{objectName}/") + public void deleteObject(@PathVariable String bucketName, @PathVariable String objectName) { template.removeObject(bucketName, objectName); } diff --git a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/service/MinioTemplate.java b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/service/MinioTemplate.java index 396b82f90..35e822eff 100755 --- a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/service/MinioTemplate.java +++ b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/common/minio/service/MinioTemplate.java @@ -23,8 +23,10 @@ import io.minio.ObjectStat; import io.minio.Result; import io.minio.messages.Bucket; import io.minio.messages.Item; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; import java.io.InputStream; import java.util.ArrayList; @@ -36,23 +38,20 @@ import java.util.Optional; * * @author lengleng */ -@NoArgsConstructor -@AllArgsConstructor -public class MinioTemplate { - - private String endpoint; - private String accessKey; - private String secretKey; - +@RequiredArgsConstructor +public class MinioTemplate implements InitializingBean { + private final String endpoint; + private final String accessKey; + private final String secretKey; + private MinioClient client; /** * 创建bucket * * @param bucketName bucket名称 - * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#makeBucket */ - public void createBucket(String bucketName) throws Exception { - MinioClient client = getMinioClient(); + @SneakyThrows + public void createBucket(String bucketName) { if (!client.bucketExists(bucketName)) { client.makeBucket(bucketName); } @@ -63,24 +62,25 @@ public class MinioTemplate { *

* https://docs.minio.io/cn/java-client-api-reference.html#listBuckets */ - public List getAllBuckets() throws Exception { - return getMinioClient().listBuckets(); + @SneakyThrows + public List getAllBuckets() { + return client.listBuckets(); } /** * @param bucketName bucket名称 - * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#listBuckets */ - public Optional getBucket(String bucketName) throws Exception { - return getMinioClient().listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst(); + @SneakyThrows + public Optional getBucket(String bucketName) { + return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst(); } /** * @param bucketName bucket名称 - * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeBucket */ - public void removeBucket(String bucketName) throws Exception { - getMinioClient().removeBucket(bucketName); + @SneakyThrows + public void removeBucket(String bucketName) { + client.removeBucket(bucketName); } /** @@ -89,16 +89,16 @@ public class MinioTemplate { * @param bucketName bucket名称 * @param prefix 前缀 * @param recursive 是否递归查询 - * @return - * @throws Exception + * @return MinioItem 列表 */ - public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws Exception { - List objectList = new ArrayList(); - Iterable> objectsIterator = getMinioClient() + @SneakyThrows + public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) { + List objectList = new ArrayList<>(); + Iterable> objectsIterator = client .listObjects(bucketName, prefix, recursive); while (objectsIterator.iterator().hasNext()) { - objectList.add(objectsIterator.iterator().next().get()); + objectList.add(new MinioItem(objectsIterator.iterator().next().get())); } return objectList; } @@ -110,10 +110,10 @@ public class MinioTemplate { * @param objectName 文件名称 * @param expires 过期时间 <=7 * @return url - * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#getObject */ - public String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception { - return getMinioClient().presignedGetObject(bucketName, objectName, expires); + @SneakyThrows + public String getObjectURL(String bucketName, String objectName, Integer expires) { + return client.presignedGetObject(bucketName, objectName, expires); } /** @@ -122,10 +122,10 @@ public class MinioTemplate { * @param bucketName bucket名称 * @param objectName 文件名称 * @return 二进制流 - * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#getObject */ - public InputStream getObject(String bucketName, String objectName) throws Exception { - return getMinioClient().getObject(bucketName, objectName); + @SneakyThrows + public InputStream getObject(String bucketName, String objectName) { + return client.getObject(bucketName, objectName); } /** @@ -137,7 +137,7 @@ public class MinioTemplate { * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject */ public void putObject(String bucketName, String objectName, InputStream stream) throws Exception { - getMinioClient().putObject(bucketName, objectName, stream, stream.available(), "application/octet-stream"); + client.putObject(bucketName, objectName, stream, stream.available(), "application/octet-stream"); } /** @@ -151,7 +151,7 @@ public class MinioTemplate { * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject */ public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception { - getMinioClient().putObject(bucketName, objectName, stream, size, contextType); + client.putObject(bucketName, objectName, stream, size, contextType); } /** @@ -162,7 +162,7 @@ public class MinioTemplate { * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject */ public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception { - return getMinioClient().statObject(bucketName, objectName); + return client.statObject(bucketName, objectName); } /** @@ -173,17 +173,15 @@ public class MinioTemplate { * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject */ public void removeObject(String bucketName, String objectName) throws Exception { - getMinioClient().removeObject(bucketName, objectName); + client.removeObject(bucketName, objectName); } - - /** - * 获取minio 原生客户端 - * - * @return - * @throws Exception - */ - public MinioClient getMinioClient() throws Exception { - return new MinioClient(endpoint, accessKey, secretKey); + @Override + public void afterPropertiesSet() throws Exception { + Assert.hasText(endpoint, "Minio url 为空"); + Assert.hasText(accessKey, "Minio accessKey为空"); + Assert.hasText(secretKey, "Minio secretKey为空"); + this.client = new MinioClient(endpoint, accessKey, secretKey); } + } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxAuth2ExceptionSerializer.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxAuth2ExceptionSerializer.java index c7ba08f7b..16f566eef 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxAuth2ExceptionSerializer.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxAuth2ExceptionSerializer.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.security.exception.PigxAuth2Exception; +import lombok.SneakyThrows; import java.io.IOException; @@ -37,7 +38,8 @@ public class PigxAuth2ExceptionSerializer extends StdSerializer diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java index 9f40c1bf3..5a568ba98 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java @@ -21,6 +21,7 @@ import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.security.annotation.Inner; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -43,8 +44,9 @@ import javax.servlet.http.HttpServletRequest; public class PigxSecurityInnerAspect { private final HttpServletRequest request; + @SneakyThrows @Around("@annotation(inner)") - public Object around(ProceedingJoinPoint point, Inner inner) throws Throwable { + public Object around(ProceedingJoinPoint point, Inner inner) { String header = request.getHeader(SecurityConstants.FROM); if (inner.value() && !StrUtil.equals(SecurityConstants.FROM_IN, header)) { log.warn("访问接口 {} 没有权限", point.getSignature().getName()); diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxWebResponseExceptionTranslator.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxWebResponseExceptionTranslator.java index b6989b13c..8e54cf32e 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxWebResponseExceptionTranslator.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxWebResponseExceptionTranslator.java @@ -45,7 +45,7 @@ public class PigxWebResponseExceptionTranslator implements WebResponseExceptionT private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer(); @Override - public ResponseEntity translate(Exception e) throws Exception { + public ResponseEntity translate(Exception e) { // Try to extract a SpringSecurityException from the stacktrace Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e); diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java index 0bc6dde08..9cd4645b5 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.security.core.AuthenticationException; @@ -46,8 +47,9 @@ public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint private final ObjectMapper objectMapper; @Override + @SneakyThrows public void commence(HttpServletRequest request, HttpServletResponse response, - AuthenticationException authException) throws IOException { + AuthenticationException authException) { response.setCharacterEncoding(CommonConstants.UTF8); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); R result = new R<>(); diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginConfiguration.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginConfiguration.java new file mode 100644 index 000000000..6e90c8464 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginConfiguration.java @@ -0,0 +1,68 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import com.netflix.hystrix.HystrixCommand; +import feign.Feign; +import feign.RequestInterceptor; +import feign.hystrix.HystrixFeign; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.openfeign.FeignContext; +import org.springframework.cloud.security.oauth2.client.AccessTokenContextRelay; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.security.oauth2.client.OAuth2ClientContext; +import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; + +/** + * fegin 配置增强 + * + * @author L.cm + */ +@Configuration +@ConditionalOnClass(Feign.class) +public class PigxFeginConfiguration { + + @Bean + @ConditionalOnProperty("security.oauth2.client.client-id") + public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext, + OAuth2ProtectedResourceDetails resource, + AccessTokenContextRelay accessTokenContextRelay) { + return new PigxFeignClientInterceptor(oAuth2ClientContext, resource, accessTokenContextRelay); + } + + @Configuration + @ConditionalOnClass({HystrixCommand.class, HystrixFeign.class}) + protected static class HystrixFeignConfiguration { + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + @ConditionalOnProperty("feign.hystrix.enabled") + public Feign.Builder feignHystrixBuilder(FeignContext feignContext) { + return PigxHystrixFeign.builder(feignContext) + .decode404() + .errorDecoder(new PigxFeginErrorDecoder()); + } + } + +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginErrorDecoder.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginErrorDecoder.java new file mode 100644 index 000000000..6ce2c2ec4 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginErrorDecoder.java @@ -0,0 +1,129 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import cn.hutool.core.io.IoUtil; +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.security.util.ConcurrentDateFormat; +import feign.Response; +import feign.RetryableException; +import feign.codec.ErrorDecoder; +import org.springframework.lang.Nullable; + +import java.io.IOException; +import java.io.Reader; +import java.text.ParseException; +import java.time.ZoneId; +import java.util.Collection; +import java.util.Date; +import java.util.Map; +import java.util.TimeZone; + +import static feign.Util.checkNotNull; +import static java.lang.String.format; +import static java.util.Locale.US; +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * 异常处理,将返回的数据反序列化成 R + * + * @author L.cm + */ +public class PigxFeginErrorDecoder extends ErrorDecoder.Default { + private final RetryAfterDecoder retryAfterDecoder = new RetryAfterDecoder(); + private static final String REGEX = "^[0-9]+$"; + + + @Override + public Exception decode(String methodKey, Response response) { + PigxFeginException exception = errorStatus(methodKey, response); + Date retryAfter = retryAfterDecoder.apply(firstOrNull(response.headers())); + return new RetryableException(exception.getMessage(), exception, retryAfter); + } + + private static PigxFeginException errorStatus(String methodKey, Response response) { + try { + if (response.body() != null) { + Reader reader = response.body().asReader(); + return new PigxFeginException(R.builder() + .msg(IoUtil.read(reader)) + .code(CommonConstants.FAIL).build()); + } + } catch (IOException ignored) { // NOPMD + } + String message = format("status %s reading %s", response.status(), methodKey); + return new PigxFeginException(message); + } + + @Nullable + private T firstOrNull(Map> map) { + String key = feign.Util.RETRY_AFTER; + if (map.containsKey(key) && !map.get(key).isEmpty()) { + return map.get(key).iterator().next(); + } + return null; + } + + /** + * Decodes a {@link feign.Util#RETRY_AFTER} header into an absolute date, if possible.
See Retry-After format + */ + static class RetryAfterDecoder { + + static final ConcurrentDateFormat RFC822_FORMAT = ConcurrentDateFormat.of + ("EEE, dd MMM yyyy HH:mm:ss 'GMT'", US, TimeZone.getTimeZone(ZoneId.of("GMT"))); + private final ConcurrentDateFormat rfc822Format; + + RetryAfterDecoder() { + this(RFC822_FORMAT); + } + + RetryAfterDecoder(ConcurrentDateFormat rfc822Format) { + this.rfc822Format = checkNotNull(rfc822Format, "rfc822Format"); + } + + private long currentTimeMillis() { + return System.currentTimeMillis(); + } + + /** + * returns a date that corresponds to the first time a request can be retried. + * + * @param retryAfter String in Retry-After format + */ + @Nullable + Date apply(@Nullable String retryAfter) { + if (retryAfter == null) { + return null; + } + if (retryAfter.matches(REGEX)) { + long deltaMillis = SECONDS.toMillis(Long.parseLong(retryAfter)); + return new Date(currentTimeMillis() + deltaMillis); + } + try { + return rfc822Format.parse(retryAfter); + } catch (ParseException ignored) { + return null; + } + } + } +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginException.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginException.java new file mode 100644 index 000000000..e036fe800 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginException.java @@ -0,0 +1,57 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.util.R; +import lombok.Getter; + +/** + * Fegin 异常 + * + * @author L.cm + */ +public class PigxFeginException extends RuntimeException { + @Getter + private final R result; + + public PigxFeginException(R result) { + super(result.getMsg()); + this.result = result; + } + + public PigxFeginException(String message) { + super(message); + this.result = R.builder() + .code(CommonConstants.FAIL) + .msg(message).build(); + } + + /** + * 提高性能 + * + * @return {Throwable} + */ + @Override + public Throwable fillInStackTrace() { + return this; + } +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginFallbackFactory.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginFallbackFactory.java new file mode 100644 index 000000000..97777a01b --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeginFallbackFactory.java @@ -0,0 +1,57 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import feign.hystrix.FallbackFactory; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cglib.proxy.Enhancer; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * 默认 Fallback,避免写过多fallback类 + * + * @param 泛型标记 + * @author L.cm + */ +@Slf4j +@NoArgsConstructor +public final class PigxFeginFallbackFactory implements FallbackFactory { + public static final PigxFeginFallbackFactory INSTANCE = new PigxFeginFallbackFactory(); + private static final ConcurrentMap, Object> FALLBACK_MAP = new ConcurrentHashMap<>(); + + @SuppressWarnings("unchecked") + public T create(final Class type, final Throwable cause) { + return (T) FALLBACK_MAP.computeIfAbsent(type, key -> { + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(key); + enhancer.setCallback(new PigxFeignFallbackMethod(type, cause)); + return enhancer.create(); + }); + } + + @Override + public T create(Throwable cause) { + return null; + } +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignClientConfiguration.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignClientConfiguration.java deleted file mode 100644 index c9c4fee6e..000000000 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignClientConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - * - */ - -package com.pig4cloud.pigx.common.security.feign; - -import feign.RequestInterceptor; -import lombok.AllArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.security.oauth2.client.AccessTokenContextRelay; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.oauth2.client.OAuth2ClientContext; -import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; - -/** - * @author lengleng - * @date 2018/6/22 - * feign 拦截器传递 header 中oauth token, - * 使用hystrix 的信号量模式 - */ -@Configuration -@AllArgsConstructor -@ConditionalOnProperty("security.oauth2.client.client-id") -public class PigxFeignClientConfiguration { - @Bean - public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext, - OAuth2ProtectedResourceDetails resource, - AccessTokenContextRelay accessTokenContextRelay) { - return new PigxFeignClientInterceptor(oAuth2ClientContext, resource,accessTokenContextRelay); - } -} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignFallbackMethod.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignFallbackMethod.java new file mode 100644 index 000000000..3e6542b58 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxFeignFallbackMethod.java @@ -0,0 +1,38 @@ +package com.pig4cloud.pigx.common.security.feign; + +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.util.R; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cglib.proxy.MethodInterceptor; +import org.springframework.cglib.proxy.MethodProxy; +import org.springframework.lang.Nullable; + +import java.lang.reflect.Method; + +/** + * @author lengleng + * @date 2019-01-22 + */ +@Slf4j +@AllArgsConstructor +public class PigxFeignFallbackMethod implements MethodInterceptor { + private Class type; + private Throwable cause; + + @Nullable + @Override + public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) { + log.error("Fallback class:[{}] method:[{}] message:[{}]", + type.getName(), method.getName(), cause.getMessage()); + + if (R.class == method.getReturnType()) { + final R result = cause instanceof PigxFeginException ? + ((PigxFeginException) cause).getResult() : R.builder() + .code(CommonConstants.FAIL) + .msg(cause.getMessage()).build(); + return result; + } + return null; + } +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixFeign.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixFeign.java new file mode 100644 index 000000000..640e1624c --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixFeign.java @@ -0,0 +1,289 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import com.netflix.hystrix.HystrixCommand; +import feign.*; +import feign.codec.Decoder; +import feign.codec.Encoder; +import feign.codec.ErrorDecoder; +import feign.hystrix.FallbackFactory; +import feign.hystrix.HystrixDelegatingContract; +import feign.hystrix.SetterFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.FeignContext; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * 自定义 Hystrix Feign 实现默认 fallBack + * + * @author L.cm + */ +public class PigxHystrixFeign { + + public static PigxHystrixFeign.Builder builder(FeignContext feignContext) { + return new PigxHystrixFeign.Builder(feignContext); + } + + public static final class Builder extends Feign.Builder { + private Contract contract = new Contract.Default(); + private SetterFactory setterFactory = new SetterFactory.Default(); + private final FeignContext feignContext; + + public Builder(FeignContext feignContext) { + this.feignContext = feignContext; + } + + /** + * Allows you to override hystrix properties such as thread pools and command keys. + */ + public PigxHystrixFeign.Builder setterFactory(SetterFactory setterFactory) { + this.setterFactory = setterFactory; + return this; + } + + @Override + public T target(Target target) { + Class targetType = target.type(); + FeignClient feignClient = AnnotatedElementUtils.getMergedAnnotation(targetType, FeignClient.class); + String factoryName = feignClient.name(); + SetterFactory setterFactoryBean = this.getOptional(factoryName, feignContext, SetterFactory.class); + if (setterFactoryBean != null) { + this.setterFactory(setterFactoryBean); + } + Class fallback = feignClient.fallback(); + if (fallback != void.class) { + return targetWithFallback(factoryName, feignContext, target, this, fallback); + } + Class fallbackFactory = feignClient.fallbackFactory(); + if (fallbackFactory != void.class) { + return targetWithFallbackFactory(factoryName, feignContext, target, this, fallbackFactory); + } + return build().newInstance(target); + } + + @SuppressWarnings("unchecked") + private T targetWithFallbackFactory(String feignClientName, FeignContext context, + Target target, + PigxHystrixFeign.Builder builder, + Class fallbackFactoryClass) { + FallbackFactory fallbackFactory = (FallbackFactory) + getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class); + /* We take a sample fallback from the fallback factory to check if it returns a fallback + that is compatible with the annotated feign interface. */ + Object exampleFallback = fallbackFactory.create(new RuntimeException()); + Assert.notNull(exampleFallback, + String.format( + "Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!", + feignClientName)); + if (!target.type().isAssignableFrom(exampleFallback.getClass())) { + throw new IllegalStateException( + String.format( + "Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'", + feignClientName, exampleFallback.getClass(), target.type())); + } + return builder.target(target, fallbackFactory); + } + + + private T targetWithFallback(String feignClientName, FeignContext context, + Target target, + PigxHystrixFeign.Builder builder, Class fallback) { + T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type()); + return builder.target(target, fallbackInstance); + } + + @SuppressWarnings("unchecked") + private T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context, + Class beanType, Class targetType) { + Object fallbackInstance = context.getInstance(feignClientName, beanType); + if (fallbackInstance == null) { + throw new IllegalStateException(String.format( + "No %s instance of type %s found for feign client %s", + fallbackMechanism, beanType, feignClientName)); + } + + if (!targetType.isAssignableFrom(beanType)) { + throw new IllegalStateException( + String.format( + "Incompatible %s instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s", + fallbackMechanism, beanType, targetType, feignClientName)); + } + return (T) fallbackInstance; + } + + @Nullable + private T getOptional(String feignClientName, FeignContext context, Class beanType) { + return context.getInstance(feignClientName, beanType); + } + + /** + * @see #target(Class, String, Object) + */ + public T target(Target target, @Nullable T fallback) { + return build(fallback != null ? new FallbackFactory.Default(fallback) : null) + .newInstance(target); + } + + /** + * @see #target(Class, String, FallbackFactory) + */ + public T target(Target target, FallbackFactory fallbackFactory) { + return build(fallbackFactory).newInstance(target); + } + + /** + * Like {@link Feign#newInstance(Target)}, except with {@link HystrixCommand + * fallback} support. + * + *

Fallbacks are known values, which you return when there's an error invoking an http + * method. For example, you can return a cached result as opposed to raising an error to the + * caller. To use this feature, pass a safe implementation of your target interface as the last + * parameter. + *

+ * Here's an example: + *

+		 * {@code
+		 *
+		 * // When dealing with fallbacks, it is less tedious to keep interfaces small.
+		 * interface GitHub {
+		 *   @RequestLine("GET /repos/{owner}/{repo}/contributors")
+		 *   List contributors(@Param("owner") String owner, @Param("repo") String repo);
+		 * }
+		 *
+		 * // This instance will be invoked if there are errors of any kind.
+		 * GitHub fallback = (owner, repo) -> {
+		 *   if (owner.equals("Netflix") && repo.equals("feign")) {
+		 *     return Arrays.asList("stuarthendren"); // inspired this approach!
+		 *   } else {
+		 *     return Collections.emptyList();
+		 *   }
+		 * };
+		 *
+		 * GitHub github = HystrixFeign.builder()
+		 *                             ...
+		 *                             .target(GitHub.class, "https://api.github.com", fallback);
+		 * }
+ * + * @see #target(Target, Object) + */ + public T target(Class apiType, String url, T fallback) { + return target(new Target.HardCodedTarget(apiType, url), fallback); + } + + /** + * Same as {@link #target(Class, String, T)}, except you can inspect a source exception before + * creating a fallback object. + */ + public T target(Class apiType, String url, FallbackFactory fallbackFactory) { + return target(new Target.HardCodedTarget(apiType, url), fallbackFactory); + } + + @Override + public Feign.Builder invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) { + throw new UnsupportedOperationException(); + } + + @Override + public PigxHystrixFeign.Builder contract(Contract contract) { + this.contract = contract; + return this; + } + + @Override + public Feign build() { + return build(null); + } + + /** + * Configures components needed for hystrix integration. + */ + Feign build(@Nullable final FallbackFactory nullableFallbackFactory) { + super.invocationHandlerFactory((target, dispatch) -> + new PigxHystrixInvocationHandler(target, dispatch, setterFactory, nullableFallbackFactory)); + super.contract(new HystrixDelegatingContract(contract)); + return super.build(); + } + + @Override + public PigxHystrixFeign.Builder logLevel(Logger.Level logLevel) { + return (PigxHystrixFeign.Builder) super.logLevel(logLevel); + } + + @Override + public PigxHystrixFeign.Builder client(Client client) { + return (PigxHystrixFeign.Builder) super.client(client); + } + + @Override + public PigxHystrixFeign.Builder retryer(Retryer retryer) { + return (PigxHystrixFeign.Builder) super.retryer(retryer); + } + + @Override + public PigxHystrixFeign.Builder logger(Logger logger) { + return (PigxHystrixFeign.Builder) super.logger(logger); + } + + @Override + public PigxHystrixFeign.Builder encoder(Encoder encoder) { + return (PigxHystrixFeign.Builder) super.encoder(encoder); + } + + @Override + public PigxHystrixFeign.Builder decoder(Decoder decoder) { + return (PigxHystrixFeign.Builder) super.decoder(decoder); + } + + @Override + public PigxHystrixFeign.Builder mapAndDecode(ResponseMapper mapper, Decoder decoder) { + return (PigxHystrixFeign.Builder) super.mapAndDecode(mapper, decoder); + } + + @Override + public PigxHystrixFeign.Builder decode404() { + return (PigxHystrixFeign.Builder) super.decode404(); + } + + @Override + public PigxHystrixFeign.Builder errorDecoder(ErrorDecoder errorDecoder) { + return (PigxHystrixFeign.Builder) super.errorDecoder(errorDecoder); + } + + @Override + public PigxHystrixFeign.Builder options(Request.Options options) { + return (PigxHystrixFeign.Builder) super.options(options); + } + + @Override + public PigxHystrixFeign.Builder requestInterceptor(RequestInterceptor requestInterceptor) { + return (PigxHystrixFeign.Builder) super.requestInterceptor(requestInterceptor); + } + + @Override + public PigxHystrixFeign.Builder requestInterceptors(Iterable requestInterceptors) { + return (PigxHystrixFeign.Builder) super.requestInterceptors(requestInterceptors); + } + } + +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixInvocationHandler.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixInvocationHandler.java new file mode 100644 index 000000000..eb1896090 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/PigxHystrixInvocationHandler.java @@ -0,0 +1,217 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.feign; + +import com.netflix.hystrix.HystrixCommand; +import com.netflix.hystrix.HystrixCommand.Setter; +import feign.InvocationHandlerFactory.MethodHandler; +import feign.Target; +import feign.hystrix.FallbackFactory; +import feign.hystrix.SetterFactory; +import org.springframework.lang.Nullable; +import rx.Completable; +import rx.Observable; +import rx.Single; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import static feign.Util.checkNotNull; + +/** + * @author L.cm + *

+ * 降级注入 + */ +public final class PigxHystrixInvocationHandler implements InvocationHandler { + private static final String EQUALS = "equals"; + private static final String HASH_CODE = "hashCode"; + private static final String TO_STRING = "toString"; + private final Target target; + private final Map dispatch; + @Nullable + private final FallbackFactory fallbackFactory; + private final Map fallbackMethodMap; + private final Map setterMethodMap; + + PigxHystrixInvocationHandler( + Target target, Map dispatch, + SetterFactory setterFactory, + FallbackFactory fallbackFactory) { + this.target = checkNotNull(target, "target"); + this.dispatch = checkNotNull(dispatch, "dispatch"); + this.fallbackFactory = fallbackFactory; + this.fallbackMethodMap = toFallbackMethod(dispatch); + this.setterMethodMap = toSetters(setterFactory, target, dispatch.keySet()); + } + + /** + * If the method param of InvocationHandler.invoke is not accessible, i.e in a package-private + * interface, the fallback call in hystrix command will fail cause of access restrictions. But + * methods in dispatch are copied methods. So setting access to dispatch method doesn't take + * effect to the method in InvocationHandler.invoke. Use map to store a copy of method to invoke + * the fallback to bypass this and reducing the count of reflection calls. + * + * @return cached methods map for fallback invoking + */ + private static Map toFallbackMethod(Map dispatch) { + Map result = new LinkedHashMap<>(dispatch.size()); + for (Method method : dispatch.keySet()) { + method.setAccessible(true); + result.put(method, method); + } + return result; + } + + /** + * Process all methods in the target so that appropriate setters are created. + */ + private static Map toSetters( + SetterFactory setterFactory, Target target, Set methods) { + Map result = new LinkedHashMap<>(methods.size()); + for (Method method : methods) { + method.setAccessible(true); + result.put(method, setterFactory.create(target, method)); + } + return result; + } + + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + // early exit if the invoked method is from java.lang.Object + // code is the same as ReflectiveFeign.FeignInvocationHandler + if (EQUALS.equals(method.getName())) { + try { + Object otherHandler = args.length > 0 && args[0] != null + ? Proxy.getInvocationHandler(args[0]) : null; + return equals(otherHandler); + } catch (IllegalArgumentException e) { + return false; + } + } else if (HASH_CODE.equals(method.getName())) { + return hashCode(); + } else if (TO_STRING.equals(method.getName())) { + return toString(); + } + + HystrixCommand hystrixCommand = new HystrixCommand(setterMethodMap.get(method)) { + @Override + protected Object run() throws Exception { + try { + return PigxHystrixInvocationHandler.this.dispatch.get(method).invoke(args); + } catch (Exception e) { + throw e; + } catch (Throwable t) { + throw (Error) t; + } + } + + @Override + @Nullable + @SuppressWarnings("unchecked") + protected Object getFallback() { + Object fallback; + try { + if (fallbackFactory == null) { + fallback = PigxFeginFallbackFactory.INSTANCE.create(target.type(), getExecutionException()); + } else { + fallback = fallbackFactory.create(getExecutionException()); + } + Object result = fallbackMethodMap.get(method).invoke(fallback, args); + if (isReturnsHystrixCommand(method)) { + return ((HystrixCommand) result).execute(); + } else if (isReturnsObservable(method)) { + // Create a cold Observable + return ((Observable) result).toBlocking().first(); + } else if (isReturnsSingle(method)) { + // Create a cold Observable as a Single + return ((Single) result).toObservable().toBlocking().first(); + } else if (isReturnsCompletable(method)) { + ((Completable) result).await(); + return null; + } else { + return result; + } + } catch (IllegalAccessException e) { + // shouldn't happen as method is public due to being an interface + throw new AssertionError(e); + } catch (InvocationTargetException e) { + // Exceptions on fallback are tossed by Hystrix + throw new AssertionError(e.getCause()); + } + } + }; + + if (isReturnsHystrixCommand(method)) { + return hystrixCommand; + } else if (isReturnsObservable(method)) { + // Create a cold Observable + return hystrixCommand.toObservable(); + } else if (isReturnsSingle(method)) { + // Create a cold Observable as a Single + return hystrixCommand.toObservable().toSingle(); + } else if (isReturnsCompletable(method)) { + return hystrixCommand.toObservable().toCompletable(); + } + return hystrixCommand.execute(); + } + + private boolean isReturnsCompletable(Method method) { + return Completable.class.isAssignableFrom(method.getReturnType()); + } + + private boolean isReturnsHystrixCommand(Method method) { + return HystrixCommand.class.isAssignableFrom(method.getReturnType()); + } + + private boolean isReturnsObservable(Method method) { + return Observable.class.isAssignableFrom(method.getReturnType()); + } + + private boolean isReturnsSingle(Method method) { + return Single.class.isAssignableFrom(method.getReturnType()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PigxHystrixInvocationHandler) { + PigxHystrixInvocationHandler other = (PigxHystrixInvocationHandler) obj; + return target.equals(other.target); + } + return false; + } + + @Override + public int hashCode() { + return target.hashCode(); + } + + @Override + public String toString() { + return target.toString(); + } +} diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/package-info.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/package-info.java new file mode 100644 index 000000000..ab9363e5e --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/feign/package-info.java @@ -0,0 +1,33 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +/** + * Hystrix 默认 fallback + *

+ * DefaultProperties: https://github.com/Netflix/Hystrix/issues/1446 + * + * @author L.cm + */ +@NonNullApi +@NonNullFields +package com.pig4cloud.pigx.common.security.feign; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java index db6d75a0d..fb23fca7d 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationFilter.java @@ -20,12 +20,12 @@ package com.pig4cloud.pigx.common.security.mobile; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import lombok.Getter; import lombok.Setter; +import lombok.SneakyThrows; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.AuthenticationEntryPoint; @@ -62,11 +62,12 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing } @Override + @SneakyThrows public Authentication attemptAuthentication(HttpServletRequest request, - HttpServletResponse response) throws AuthenticationException { + HttpServletResponse response) { if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) { throw new AuthenticationServiceException( - "Authentication method not supported: " + request.getMethod()); + "Authentication method not supported: " + request.getMethod()); } String mobile = obtainMobile(request); @@ -93,11 +94,11 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing logger.debug("Authentication request failed: " + failed); eventPublisher.publishAuthenticationFailure(new BadCredentialsException(failed.getMessage(), failed), - new PreAuthenticatedAuthenticationToken("access-token", "N/A")); + new PreAuthenticatedAuthenticationToken("access-token", "N/A")); try { authenticationEntryPoint.commence(request, response, - new UsernameNotFoundException(failed.getMessage(), failed)); + new UsernameNotFoundException(failed.getMessage(), failed)); } catch (Exception e) { logger.error("authenticationEntryPoint handle error:{}", failed); } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationProvider.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationProvider.java index 4896835af..778eba908 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationProvider.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationProvider.java @@ -21,12 +21,12 @@ import com.pig4cloud.pigx.common.security.component.PigxPreAuthenticationChecks; import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService; import lombok.Getter; import lombok.Setter; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.support.MessageSourceAccessor; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.SpringSecurityMessageSource; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsChecker; @@ -47,7 +47,8 @@ public class MobileAuthenticationProvider implements AuthenticationProvider { private PigxUserDetailsService userDetailsService; @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { + @SneakyThrows + public Authentication authenticate(Authentication authentication) { MobileAuthenticationToken mobileAuthenticationToken = (MobileAuthenticationToken) authentication; String principal = mobileAuthenticationToken.getPrincipal().toString(); diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationToken.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationToken.java index f059cab92..be56bf8d9 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationToken.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/mobile/MobileAuthenticationToken.java @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.common.security.mobile; +import lombok.SneakyThrows; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityCoreVersion; @@ -30,46 +31,47 @@ import java.util.Collection; */ public class MobileAuthenticationToken extends AbstractAuthenticationToken { - private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; - private final Object principal; + private final Object principal; - public MobileAuthenticationToken(String mobile) { - super(null); - this.principal = mobile; - setAuthenticated(false); - } + public MobileAuthenticationToken(String mobile) { + super(null); + this.principal = mobile; + setAuthenticated(false); + } - public MobileAuthenticationToken(Object principal, + public MobileAuthenticationToken(Object principal, Collection authorities) { - super(authorities); - this.principal = principal; - super.setAuthenticated(true); - } + super(authorities); + this.principal = principal; + super.setAuthenticated(true); + } - @Override - public Object getPrincipal() { - return this.principal; - } + @Override + public Object getPrincipal() { + return this.principal; + } - @Override - public Object getCredentials() { - return null; - } + @Override + public Object getCredentials() { + return null; + } - @Override - public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { - if (isAuthenticated) { - throw new IllegalArgumentException( - "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); - } + @Override + @SneakyThrows + public void setAuthenticated(boolean isAuthenticated) { + if (isAuthenticated) { + throw new IllegalArgumentException( + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + } - super.setAuthenticated(false); - } + super.setAuthenticated(false); + } - @Override - public void eraseCredentials() { - super.eraseCredentials(); - } + @Override + public void eraseCredentials() { + super.eraseCredentials(); + } } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java index 6a6007b38..ea5c11d42 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java @@ -18,6 +18,7 @@ package com.pig4cloud.pigx.common.security.service; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import lombok.SneakyThrows; import org.springframework.cache.annotation.Cacheable; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.provider.ClientDetails; @@ -45,8 +46,9 @@ public class PigxClientDetailsService extends JdbcClientDetailsService { * @throws InvalidClientException */ @Override + @SneakyThrows @Cacheable(value = SecurityConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null") - public ClientDetails loadClientByClientId(String clientId) throws InvalidClientException { + public ClientDetails loadClientByClientId(String clientId) { return super.loadClientByClientId(clientId); } } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java index 15d00bffc..abc4cee35 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java @@ -26,6 +26,7 @@ import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; @@ -60,7 +61,8 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService { * @throws UsernameNotFoundException */ @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + @SneakyThrows + public UserDetails loadUserByUsername(String username) { Cache cache = cacheManager.getCache("user_details"); if (cache != null && cache.get(username) != null) { return (PigxUser) cache.get(username).get(); @@ -81,7 +83,8 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService { * @throws UsernameNotFoundException */ @Override - public UserDetails loadUserBySocial(String inStr) throws UsernameNotFoundException { + @SneakyThrows + public UserDetails loadUserBySocial(String inStr) { return getUserDetails(remoteUserService.social(inStr, SecurityConstants.FROM_IN)); } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/AuthUtils.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/AuthUtils.java index 755183d75..3af62cf7a 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/AuthUtils.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/AuthUtils.java @@ -19,6 +19,7 @@ package com.pig4cloud.pigx.common.security.util; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.CharsetUtil; +import lombok.SneakyThrows; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; @@ -43,8 +44,8 @@ public class AuthUtils { * @throws RuntimeException if the Basic header is not present or is not valid * Base64 */ - public String[] extractAndDecodeHeader(String header) - throws IOException { + @SneakyThrows + public String[] extractAndDecodeHeader(String header) { byte[] base64Token = header.substring(6).getBytes("UTF-8"); byte[] decoded; @@ -70,10 +71,9 @@ public class AuthUtils { * * @param request * @return - * @throws IOException */ - public String[] extractAndDecodeHeader(HttpServletRequest request) - throws IOException { + @SneakyThrows + public String[] extractAndDecodeHeader(HttpServletRequest request) { String header = request.getHeader(HttpHeaders.AUTHORIZATION); if (header == null || !header.startsWith(BASIC_)) { diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java new file mode 100644 index 000000000..e0416ca46 --- /dev/null +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java @@ -0,0 +1,90 @@ +/* + * ************************************************************************* + * Copyright (c) 2018-2025, dreamlu.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: chunmeng.lu (qq596392912@gmail.com) + * ************************************************************************* + */ + +package com.pig4cloud.pigx.common.security.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Queue; +import java.util.TimeZone; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * 参考tomcat8中的并发DateFormat + *

+ * {@link SimpleDateFormat}的线程安全包装器。 + * 不使用ThreadLocal,创建足够的SimpleDateFormat对象来满足并发性要求。 + * + * @author L.cm + */ +public class ConcurrentDateFormat { + private final String format; + private final Locale locale; + private final TimeZone timezone; + private final Queue queue = new ConcurrentLinkedQueue<>(); + + private ConcurrentDateFormat(String format, Locale locale, TimeZone timezone) { + this.format = format; + this.locale = locale; + this.timezone = timezone; + SimpleDateFormat initial = createInstance(); + queue.add(initial); + } + + public static ConcurrentDateFormat of(String format) { + return new ConcurrentDateFormat(format, Locale.getDefault(), TimeZone.getDefault()); + } + + public static ConcurrentDateFormat of(String format, TimeZone timezone) { + return new ConcurrentDateFormat(format, Locale.getDefault(), timezone); + } + + public static ConcurrentDateFormat of(String format, Locale locale, TimeZone timezone) { + return new ConcurrentDateFormat(format, locale, timezone); + } + + public String format(Date date) { + SimpleDateFormat sdf = queue.poll(); + if (sdf == null) { + sdf = createInstance(); + } + String result = sdf.format(date); + queue.add(sdf); + return result; + } + + public Date parse(String source) throws ParseException { + SimpleDateFormat sdf = queue.poll(); + if (sdf == null) { + sdf = createInstance(); + } + Date result = sdf.parse(source); + queue.add(sdf); + return result; + } + + private SimpleDateFormat createInstance() { + SimpleDateFormat sdf = new SimpleDateFormat(format, locale); + sdf.setTimeZone(timezone); + return sdf; + } +} diff --git a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories index b13fe1565..19d984da1 100644 --- a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories +++ b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories @@ -1,3 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.pig4cloud.pigx.common.security.feign.PigxFeignClientConfiguration,\ + com.pig4cloud.pigx.common.security.feign.PigxFeginConfiguration,\ com.pig4cloud.pigx.common.security.service.PigxUserDetailsServiceImpl diff --git a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/TransactionConfiguration.java b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/TransactionConfiguration.java index 176b8acd2..c6676d76c 100755 --- a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/TransactionConfiguration.java +++ b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/TransactionConfiguration.java @@ -21,8 +21,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** - *@author LCN on 2017/6/26. - * + * @author LCN on 2017/6/26. * @author LCN * @since 4.1.0 */ diff --git a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/http/TransactionHttpRequestInterceptor.java b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/http/TransactionHttpRequestInterceptor.java index f46bf6181..ca7552d55 100755 --- a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/http/TransactionHttpRequestInterceptor.java +++ b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/http/TransactionHttpRequestInterceptor.java @@ -18,6 +18,7 @@ package com.pig4cloud.pigx.common.transaction.tx.springcloud.http; import com.codingapi.tx.aop.bean.TxTransactionLocal; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; @@ -34,8 +35,10 @@ import java.io.IOException; */ @Slf4j public class TransactionHttpRequestInterceptor implements ClientHttpRequestInterceptor { + @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + @SneakyThrows + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) { TxTransactionLocal txTransactionLocal = TxTransactionLocal.current(); String groupId = txTransactionLocal == null ? null : txTransactionLocal.getGroupId(); diff --git a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TransactionAspect.java b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TransactionAspect.java index c7f19b95a..e0433b356 100755 --- a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TransactionAspect.java +++ b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TransactionAspect.java @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.common.transaction.tx.springcloud.interceptor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -41,17 +42,18 @@ public class TransactionAspect implements Ordered { @Autowired private TxManagerInterceptor txManagerInterceptor; - + @SneakyThrows @Around("@annotation(com.codingapi.tx.annotation.TxTransaction)") - public Object transactionRunning(ProceedingJoinPoint point) throws Throwable { + public Object transactionRunning(ProceedingJoinPoint point) { log.debug("annotation-TransactionRunning-start---->"); Object obj = txManagerInterceptor.around(point); log.debug("annotation-TransactionRunning-end---->"); return obj; } + @SneakyThrows @Around("this(com.codingapi.tx.annotation.ITxTransaction) && execution( * *(..))") - public Object around(ProceedingJoinPoint point) throws Throwable { + public Object around(ProceedingJoinPoint point) { log.debug("interface-ITransactionRunning-start---->"); Object obj = txManagerInterceptor.around(point); log.debug("interface-ITransactionRunning-end---->"); diff --git a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java index 78aaf85af..51d1d4b43 100755 --- a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java +++ b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java @@ -18,6 +18,7 @@ package com.pig4cloud.pigx.common.transaction.tx.springcloud.interceptor; import com.codingapi.tx.aop.service.AspectBeforeService; +import lombok.SneakyThrows; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -39,7 +40,8 @@ public class TxManagerInterceptor { @Autowired private AspectBeforeService aspectBeforeService; - public Object around(ProceedingJoinPoint point) throws Throwable { + @SneakyThrows + public Object around(ProceedingJoinPoint point) { RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); String groupId = request.getHeader("tx-group"); diff --git a/pigx-config/src/main/resources/config/application-dev.yml b/pigx-config/src/main/resources/config/application-dev.yml index 2f5831775..9649e755d 100644 --- a/pigx-config/src/main/resources/config/application-dev.yml +++ b/pigx-config/src/main/resources/config/application-dev.yml @@ -99,8 +99,8 @@ security: client: # 默认放行url,如果子模块重写这里的配置就会被覆盖 ignore-urls: - - '/actuator/**' - - '/v2/api-docs' + - /actuator/** + - /v2/api-docs resource: loadBalanced: true token-info-uri: http://pigx-auth/oauth/check_token diff --git a/pigx-config/src/main/resources/config/pigx-activiti-dev.yml b/pigx-config/src/main/resources/config/pigx-activiti-dev.yml index bc971188c..d605fdfec 100644 --- a/pigx-config/src/main/resources/config/pigx-activiti-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-activiti-dev.yml @@ -13,6 +13,7 @@ security: - '/task/view/*' - '/process/resource/**' - '/modeler.html' + - '/ws/**' spring: autoconfigure: exclude: org.activiti.spring.boot.SecurityAutoConfiguration @@ -24,3 +25,10 @@ spring: username: root password: root url: jdbc:mysql://pigx-mysql:3306/pigxx_ac?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true + +# 租户表维护 +pigx: + tenant: + column: tenant_id + tables: + - oa_leave_bill diff --git a/pigx-config/src/main/resources/config/pigx-upms-biz-dev.yml b/pigx-config/src/main/resources/config/pigx-upms-biz-dev.yml index c944f8ee2..d034e6b8d 100644 --- a/pigx-config/src/main/resources/config/pigx-upms-biz-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-upms-biz-dev.yml @@ -7,12 +7,12 @@ security: scope: server # 默认放行url,子模块重写时application-dev.yml中的公共配置会被覆盖,所以要把公共配置中的放行url再写一次 ignore-urls: - - '/actuator/**' - - '/v2/api-docs' - - '/user/info/*' - - '/social/info/*' - - '/mobile/*' - - '/log/save' + - /actuator/** + - /v2/api-docs + - /user/info/* + - /social/info/* + - /mobile/* + - /log/save # 数据源 spring: @@ -44,3 +44,16 @@ minio: logging: level: com.pig4cloud.pigx.admin.mapper: debug + +# 租户表维护 +pigx: + tenant: + column: tenant_id + tables: + - sys_user + - sys_role + - sys_dept + - sys_log + - sys_social_details + - sys_dict + - sys_log diff --git a/pigx-eureka/src/main/java/com/pig4cloud/pigx/eureka/security/WebSecurityConfig.java b/pigx-eureka/src/main/java/com/pig4cloud/pigx/eureka/security/WebSecurityConfig.java index 040f89287..0eb95dbb2 100644 --- a/pigx-eureka/src/main/java/com/pig4cloud/pigx/eureka/security/WebSecurityConfig.java +++ b/pigx-eureka/src/main/java/com/pig4cloud/pigx/eureka/security/WebSecurityConfig.java @@ -22,6 +22,7 @@ package com.pig4cloud.pigx.eureka.security; * @date 2018/7/12 */ +import lombok.SneakyThrows; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -29,11 +30,12 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override - protected void configure(HttpSecurity http) throws Exception { + @SneakyThrows + protected void configure(HttpSecurity http) { http.csrf().disable() - .authorizeRequests() - .antMatchers("/actuator/**").permitAll() - .anyRequest() - .authenticated().and().httpBasic(); + .authorizeRequests() + .antMatchers("/actuator/**").permitAll() + .anyRequest() + .authenticated().and().httpBasic(); } } diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java index 7ca44118f..3fd2eb7c1 100644 --- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java +++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java @@ -22,6 +22,7 @@ import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.gateway.filter.GatewayFilter; @@ -51,7 +52,8 @@ public class PasswordDecoderFilter extends AbstractGatewayFilterFactory { @Value("${security.encode.key:1234567812345678}") private String encodeKey; - private static String decryptAES(String data, String pass) throws Exception { + @SneakyThrows + private static String decryptAES(String data, String pass) { Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); SecretKeySpec keyspec = new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM); IvParameterSpec ivspec = new IvParameterSpec(pass.getBytes()); diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java index 7c7f4ee6d..8e4b938e1 100644 --- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java +++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java @@ -27,6 +27,7 @@ import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.WebUtils; import com.pig4cloud.pigx.gateway.config.FilterIgnorePropertiesConfig; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; @@ -97,9 +98,9 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory { * 检查code * * @param request - * @throws ValidateCodeException 校验异常 */ - private void checkCode(ServerHttpRequest request) throws ValidateCodeException { + @SneakyThrows + private void checkCode(ServerHttpRequest request) { String code = request.getQueryParams().getFirst("code"); if (StrUtil.isBlank(code)) { diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java index 95541ebbc..dcd9772b2 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDept.java @@ -22,7 +22,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -40,7 +39,6 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_dept") public class SysDept extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDeptRelation.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDeptRelation.java index c2bbc39d2..f51f608c8 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDeptRelation.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDeptRelation.java @@ -19,7 +19,6 @@ package com.pig4cloud.pigx.admin.api.entity; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -34,7 +33,6 @@ import lombok.EqualsAndHashCode; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_dept_relation") public class SysDeptRelation extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDict.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDict.java index 0bd60f144..8e87bc4b1 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDict.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysDict.java @@ -22,7 +22,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -40,7 +39,6 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_dict") public class SysDict extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysMenu.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysMenu.java index ae9757d4f..58248a5c6 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysMenu.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysMenu.java @@ -22,7 +22,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -41,7 +40,6 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_menu") public class SysMenu extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java index 46eab38aa..246968747 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysOauthClientDetails.java @@ -21,7 +21,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -39,7 +38,6 @@ import java.io.Serializable; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_oauth_client_details") public class SysOauthClientDetails extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java index 9cf07859b..1947e35ce 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRole.java @@ -22,7 +22,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -42,7 +41,6 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_role") public class SysRole extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRoleMenu.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRoleMenu.java index ec319bca1..a6d977fc2 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRoleMenu.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRoleMenu.java @@ -19,7 +19,6 @@ package com.pig4cloud.pigx.admin.api.entity; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -34,7 +33,6 @@ import lombok.EqualsAndHashCode; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_role_menu") public class SysRoleMenu extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRouteConf.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRouteConf.java index 610b1672a..8cd501efe 100755 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRouteConf.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysRouteConf.java @@ -17,7 +17,10 @@ package com.pig4cloud.pigx.admin.api.entity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; @@ -32,7 +35,6 @@ import java.time.LocalDateTime; * @date 2018-11-06 10:17:18 */ @Data -@TableName("sys_route_conf") @EqualsAndHashCode(callSuper = true) public class SysRouteConf extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java index 82b732860..58770a13e 100755 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java @@ -19,7 +19,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -35,7 +34,6 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_social_details") public class SysSocialDetails extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java index 8a41a0f04..da1f943ca 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java @@ -22,7 +22,6 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; @@ -38,7 +37,6 @@ import java.time.LocalDateTime; * @since 2017-10-29 */ @Data -@TableName("sys_user") public class SysUser implements Serializable { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserRole.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserRole.java index 6ff63a81c..059b53297 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserRole.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUserRole.java @@ -19,7 +19,6 @@ package com.pig4cloud.pigx.admin.api.entity; -import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; @@ -34,7 +33,6 @@ import lombok.EqualsAndHashCode; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("sys_user_role") public class SysUserRole extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteLogService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteLogService.java index 356c27352..c722f174f 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteLogService.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteLogService.java @@ -20,7 +20,6 @@ package com.pig4cloud.pigx.admin.api.feign; import com.pig4cloud.pigx.admin.api.entity.SysLog; -import com.pig4cloud.pigx.admin.api.feign.factory.RemoteLogServiceFallbackFactory; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; import com.pig4cloud.pigx.common.core.util.R; @@ -33,7 +32,7 @@ import org.springframework.web.bind.annotation.RequestHeader; * @author lengleng * @date 2018/6/28 */ -@FeignClient(value = ServiceNameConstants.UMPS_SERVICE, fallbackFactory = RemoteLogServiceFallbackFactory.class) +@FeignClient(value = ServiceNameConstants.UMPS_SERVICE) public interface RemoteLogService { /** * 保存日志 diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTokenService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTokenService.java index 883931ae5..ce02e5c43 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTokenService.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteTokenService.java @@ -18,7 +18,6 @@ package com.pig4cloud.pigx.admin.api.feign; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pigx.admin.api.feign.factory.RemoteTokenServiceFallbackFactory; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; import com.pig4cloud.pigx.common.core.util.R; @@ -31,13 +30,14 @@ import java.util.Map; * @author lengleng * @date 2018/9/4 */ -@FeignClient(value = ServiceNameConstants.AUTH_SERVICE, fallbackFactory = RemoteTokenServiceFallbackFactory.class) +@FeignClient(value = ServiceNameConstants.AUTH_SERVICE) public interface RemoteTokenService { /** * 分页查询token 信息 * * @param from 内部调用标志 * @param params 分页参数 + * @param from 内部调用标志 * @return page */ @PostMapping("/token/page") @@ -48,6 +48,7 @@ public interface RemoteTokenService { * * @param from 内部调用标志 * @param token token + * @param from 内部调用标志 * @return */ @DeleteMapping("/token/{token}") diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java index 3c3100ca3..b4832a9c2 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java @@ -21,7 +21,6 @@ package com.pig4cloud.pigx.admin.api.feign; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysUser; -import com.pig4cloud.pigx.admin.api.feign.factory.RemoteUserServiceFallbackFactory; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; import com.pig4cloud.pigx.common.core.util.R; @@ -36,7 +35,7 @@ import java.util.List; * @author lengleng * @date 2018/6/22 */ -@FeignClient(value = ServiceNameConstants.UMPS_SERVICE, fallbackFactory = RemoteUserServiceFallbackFactory.class) +@FeignClient(value = ServiceNameConstants.UMPS_SERVICE) public interface RemoteUserService { /** * 通过用户名查询用户、角色信息 @@ -47,7 +46,7 @@ public interface RemoteUserService { */ @GetMapping("/user/info/{username}") R info(@PathVariable("username") String username - , @RequestHeader(SecurityConstants.FROM) String from); + , @RequestHeader(SecurityConstants.FROM) String from); /** * 通过社交账号或手机号查询用户、角色信息 @@ -58,7 +57,7 @@ public interface RemoteUserService { */ @GetMapping("/social/info/{inStr}") R social(@PathVariable("inStr") String inStr - , @RequestHeader(SecurityConstants.FROM) String from); + , @RequestHeader(SecurityConstants.FROM) String from); /** * 查询上级部门的用户信息 diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteLogServiceFallbackFactory.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteLogServiceFallbackFactory.java deleted file mode 100644 index f6b0ebd09..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteLogServiceFallbackFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - */ - -package com.pig4cloud.pigx.admin.api.feign.factory; - -import com.pig4cloud.pigx.admin.api.feign.RemoteLogService; -import com.pig4cloud.pigx.admin.api.feign.fallback.RemoteLogServiceFallbackImpl; -import feign.hystrix.FallbackFactory; -import org.springframework.stereotype.Component; - -/** - * @author lengleng - * @date 2018/9/4 - */ -@Component -public class RemoteLogServiceFallbackFactory implements FallbackFactory { - - @Override - public RemoteLogService create(Throwable throwable) { - RemoteLogServiceFallbackImpl remoteLogServiceFallback = new RemoteLogServiceFallbackImpl(); - remoteLogServiceFallback.setCause(throwable); - return remoteLogServiceFallback; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteTokenServiceFallbackFactory.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteTokenServiceFallbackFactory.java deleted file mode 100644 index ebe82bc19..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteTokenServiceFallbackFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - */ - -package com.pig4cloud.pigx.admin.api.feign.factory; - -import com.pig4cloud.pigx.admin.api.feign.RemoteTokenService; -import com.pig4cloud.pigx.admin.api.feign.fallback.RemoteTokenServiceFallbackImpl; -import feign.hystrix.FallbackFactory; -import org.springframework.stereotype.Component; - -/** - * @author lengleng - * @date 2018/9/4 - */ -@Component -public class RemoteTokenServiceFallbackFactory implements FallbackFactory { - - @Override - public RemoteTokenService create(Throwable throwable) { - RemoteTokenServiceFallbackImpl remoteTokenServiceFallback = new RemoteTokenServiceFallbackImpl(); - remoteTokenServiceFallback.setCause(throwable); - return remoteTokenServiceFallback; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteUserServiceFallbackFactory.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteUserServiceFallbackFactory.java deleted file mode 100644 index 93dbb02b4..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/factory/RemoteUserServiceFallbackFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - */ - -package com.pig4cloud.pigx.admin.api.feign.factory; - -import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; -import com.pig4cloud.pigx.admin.api.feign.fallback.RemoteUserServiceFallbackImpl; -import feign.hystrix.FallbackFactory; -import org.springframework.stereotype.Component; - -/** - * @author lengleng - * @date 2018/9/1 - */ -@Component -public class RemoteUserServiceFallbackFactory implements FallbackFactory { - - @Override - public RemoteUserService create(Throwable throwable) { - RemoteUserServiceFallbackImpl remoteUserServiceFallback = new RemoteUserServiceFallbackImpl(); - remoteUserServiceFallback.setCause(throwable); - return remoteUserServiceFallback; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteLogServiceFallbackImpl.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteLogServiceFallbackImpl.java deleted file mode 100644 index c95c1a393..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteLogServiceFallbackImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - * - */ - -package com.pig4cloud.pigx.admin.api.feign.fallback; - -import com.pig4cloud.pigx.admin.api.entity.SysLog; -import com.pig4cloud.pigx.admin.api.feign.RemoteLogService; -import com.pig4cloud.pigx.common.core.util.R; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -/** - * @author lengleng - * @date 2018/6/26 - */ -@Slf4j -@Component -public class RemoteLogServiceFallbackImpl implements RemoteLogService { - @Setter - private Throwable cause; - - /** - * 保存日志 - * - * @param sysLog - * @param from - * @return R - */ - @Override - public R saveLog(SysLog sysLog, String from) { - log.error("feign 插入日志失败", cause); - return null; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteTokenServiceFallbackImpl.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteTokenServiceFallbackImpl.java deleted file mode 100644 index a57ad391b..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteTokenServiceFallbackImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - */ - -package com.pig4cloud.pigx.admin.api.feign.fallback; - -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pigx.admin.api.feign.RemoteTokenService; -import com.pig4cloud.pigx.common.core.util.R; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import java.util.Map; - -/** - * @author lengleng - * @date 2018/9/4 - * feign token fallback - */ -@Slf4j -@Component -public class RemoteTokenServiceFallbackImpl implements RemoteTokenService { - @Setter - private Throwable cause; - - /** - * 分页查询token 信息 - * - * @param params 分页参数 - * @param from 内部调用标志 - * @return page - */ - @Override - public R getTokenPage(Map params, String from) { - log.error("调用认证中心查询token 失败", cause); - return null; - } - - /** - * 删除token - * - * @param token - * @param from 内部调用标志 - * @return - */ - @Override - public R removeTokenById(String token, String from) { - log.error("删除token 失败 {}", token, cause); - return null; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteUserServiceFallbackImpl.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteUserServiceFallbackImpl.java deleted file mode 100644 index 1702fc84a..000000000 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/fallback/RemoteUserServiceFallbackImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright (c) 2018-2025, lengleng All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the pig4cloud.com developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: lengleng (wangiegie@gmail.com) - * - */ - -package com.pig4cloud.pigx.admin.api.feign.fallback; - -import com.pig4cloud.pigx.admin.api.dto.UserInfo; -import com.pig4cloud.pigx.admin.api.entity.SysUser; -import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; -import com.pig4cloud.pigx.common.core.util.R; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * @author lengleng - * @date 2018/6/26 - */ -@Slf4j -@Component -public class RemoteUserServiceFallbackImpl implements RemoteUserService { - @Setter - private Throwable cause; - - /** - * 通过用户名查询用户、角色信息 - * - * @param username 用户名 - * @param from 内外标志 - * @return R - */ - @Override - public R info(String username, String from) { - log.error("feign 查询用户信息失败:{}", username, cause); - return null; - } - - /** - * 通过社交账号查询用户、角色信息 - * - * @param inStr appid@code - * @param from 内外标志 - * @return - */ - @Override - public R social(String inStr, String from) { - log.error("feign 查询用户信息失败:{}", inStr, cause); - return null; - } - - /** - * 查询上级部门的用户信息 - * - * @param username 用户名 - * @return R - */ - @Override - public R> ancestorUsers(String username) { - log.error("feign 查询用户上级部门用户列失败:{}", username, cause); - return null; - } -} diff --git a/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring.factories b/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 5fab2a739..000000000 --- a/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,7 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.pig4cloud.pigx.admin.api.feign.fallback.RemoteUserServiceFallbackImpl,\ - com.pig4cloud.pigx.admin.api.feign.fallback.RemoteLogServiceFallbackImpl,\ - com.pig4cloud.pigx.admin.api.feign.fallback.RemoteTokenServiceFallbackImpl,\ - com.pig4cloud.pigx.admin.api.feign.factory.RemoteUserServiceFallbackFactory,\ - com.pig4cloud.pigx.admin.api.feign.factory.RemoteLogServiceFallbackFactory,\ - com.pig4cloud.pigx.admin.api.feign.factory.RemoteTokenServiceFallbackFactory diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java index 5034827fd..d3e35deb3 100644 --- a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java @@ -21,6 +21,9 @@ import lombok.AllArgsConstructor; import org.activiti.spring.SpringProcessEngineConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @@ -39,7 +42,7 @@ public class ActivitiConfig { @Bean public SpringProcessEngineConfiguration getProcessEngineConfiguration() { SpringProcessEngineConfiguration config = - new SpringProcessEngineConfiguration(); + new SpringProcessEngineConfiguration(); // 流程图字体设置 config.setActivityFontName("宋体"); config.setAnnotationFontName("宋体"); @@ -51,4 +54,10 @@ public class ActivitiConfig { config.setDatabaseSchemaUpdate("true"); return config; } + + @Bean + @Primary + public TaskExecutor primaryTaskExecutor() { + return new ThreadPoolTaskExecutor(); + } } diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java new file mode 100644 index 000000000..012ec28cb --- /dev/null +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java @@ -0,0 +1,66 @@ +package com.pig4cloud.pigx.act.config; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.config.ChannelRegistration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.messaging.support.MessageHeaderAccessor; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.RemoteTokenServices; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + * @author new + *

+ * WebSocket配置类 + */ +@Slf4j +@Configuration +@AllArgsConstructor +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + private RemoteTokenServices tokenService; + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws") + .setAllowedOrigins("*") + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setUserDestinationPrefix("/task/"); + } + + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + registration.interceptors(new ChannelInterceptor() { + @Override + public Message preSend(Message message, MessageChannel channel) { + StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + if (StompCommand.CONNECT.equals(accessor.getCommand())) { + String tokens = accessor.getFirstNativeHeader("Authorization"); + log.info("webSocket token is {}", tokens); + if (StrUtil.isBlank(tokens)) { + return null; + } + OAuth2Authentication auth2Authentication = tokenService.loadAuthentication(tokens.split(" ")[1]); + SecurityContextHolder.getContext().setAuthentication(auth2Authentication); + accessor.setUser(() -> (String) auth2Authentication.getPrincipal()); + } + return message; + } + }); + } +} diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java index 0e2addf43..012b27613 100644 --- a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java @@ -22,11 +22,14 @@ import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.security.util.SecurityUtils; import lombok.extern.slf4j.Slf4j; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.delegate.TaskListener; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -45,18 +48,26 @@ public class LeaveProcessTaskListener implements TaskListener { */ @Override public void notify(DelegateTask delegateTask) { + SimpMessagingTemplate simpMessagingTemplate = SpringContextHolder.getBean(SimpMessagingTemplate.class); RemoteUserService userService = SpringContextHolder.getBean(RemoteUserService.class); R> result = userService.ancestorUsers(SecurityUtils.getUsername()); + List remindUserList = new ArrayList<>(); if (CollUtil.isEmpty(result.getData())) { log.info("用户 {} 不存在上级,任务单由当前用户审批", SecurityUtils.getUsername()); delegateTask.addCandidateUser(SecurityUtils.getUsername()); + remindUserList.add(SecurityUtils.getUsername()); } else { List userList = result.getData().stream().map(SysUser::getUsername).collect(Collectors.toList()); log.info("当前任务 {},由 {}处理", delegateTask.getId(), userList); delegateTask.addCandidateUsers(userList); + remindUserList.addAll(userList); } + remindUserList.forEach(user -> { + String target = String.format("%s-%s", SecurityUtils.getUsername(), TenantContextHolder.getTenantId()); + simpMessagingTemplate.convertAndSendToUser(target, "/remind", delegateTask.getName()); + }); } } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java index 10e295136..33ce4aa7a 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java @@ -23,6 +23,7 @@ import com.pig4cloud.pigx.codegen.entity.GenConfig; import com.pig4cloud.pigx.codegen.service.SysGeneratorService; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.*; @@ -55,13 +56,14 @@ public class SysGeneratorController { /** * 生成代码 */ + @SneakyThrows @PostMapping("/code") - public void generatorCode(@RequestBody GenConfig genConfig, HttpServletResponse response) throws IOException { + public void generatorCode(@RequestBody GenConfig genConfig, HttpServletResponse response) { byte[] data = sysGeneratorService.generatorCode(genConfig); response.reset(); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s.zip", genConfig.getTableName())); - response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(data.length)); + response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(data.length)); response.setContentType("application/octet-stream; charset=UTF-8"); IoUtil.write(response.getOutputStream(), Boolean.TRUE, data); diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/controller/AdminController.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/controller/AdminController.java index 788cd39a9..8dc12bb06 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/controller/AdminController.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/controller/AdminController.java @@ -25,6 +25,7 @@ import com.pig4cloud.pigx.manager.model.ModelInfo; import com.pig4cloud.pigx.manager.model.ModelName; import com.pig4cloud.pigx.manager.model.TxState; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -89,18 +90,21 @@ public class AdminController { return apiAdminService.modelInfos(path); } + @SneakyThrows @RequestMapping(value = "/compensate", method = RequestMethod.GET) - public boolean compensate(@RequestParam("path") String path) throws ServiceException { + public boolean compensate(@RequestParam("path") String path) { return apiAdminService.compensate(path); } + @SneakyThrows @RequestMapping(value = "/delCompensate", method = RequestMethod.GET) - public boolean delCompensate(@RequestParam("path") String path) throws ServiceException { + public boolean delCompensate(@RequestParam("path") String path) { return apiAdminService.delCompensate(path); } + @SneakyThrows @RequestMapping(value = "/hasCompensate", method = RequestMethod.GET) - public boolean hasCompensate() throws ServiceException { + public boolean hasCompensate() { return apiAdminService.hasCompensate(); } } diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/ApiAdminService.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/ApiAdminService.java index a9e22695f..b18cf1c5b 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/ApiAdminService.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/ApiAdminService.java @@ -21,6 +21,7 @@ import com.lorne.core.framework.exception.ServiceException; import com.pig4cloud.pigx.manager.compensate.model.TxModel; import com.pig4cloud.pigx.manager.model.ModelName; import com.pig4cloud.pigx.manager.model.TxState; +import lombok.SneakyThrows; import java.util.List; import java.util.Map; diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/impl/ApiAdminServiceImpl.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/impl/ApiAdminServiceImpl.java index 06c16969d..662cd4519 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/impl/ApiAdminServiceImpl.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/api/service/impl/ApiAdminServiceImpl.java @@ -28,6 +28,7 @@ import com.pig4cloud.pigx.manager.model.ModelName; import com.pig4cloud.pigx.manager.model.TxState; import com.pig4cloud.pigx.manager.redis.RedisServerService; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -108,7 +109,8 @@ public class ApiAdminServiceImpl implements ApiAdminService { } @Override - public boolean compensate(String path) throws ServiceException { + @SneakyThrows + public boolean compensate(String path) { return compensateService.executeCompensate(path); } diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/compensate/service/impl/CompensateServiceImpl.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/compensate/service/impl/CompensateServiceImpl.java index 52a5b8528..16656b1d1 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/compensate/service/impl/CompensateServiceImpl.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/compensate/service/impl/CompensateServiceImpl.java @@ -36,6 +36,7 @@ import com.pig4cloud.pigx.manager.model.ModelInfo; import com.pig4cloud.pigx.manager.model.ModelName; import com.pig4cloud.pigx.manager.netty.model.TxGroup; import com.pig4cloud.pigx.manager.netty.model.TxInfo; +import lombok.SneakyThrows; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -309,7 +310,8 @@ public class CompensateServiceImpl implements CompensateService { @Override - public boolean executeCompensate(String path) throws ServiceException { + @SneakyThrows + public boolean executeCompensate(String path) { String json = compensateDao.getCompensate(path); if (json == null) { @@ -326,8 +328,8 @@ public class CompensateServiceImpl implements CompensateService { return false; } - - private boolean executeCompensateMethod(String json) throws ServiceException { + @SneakyThrows + private boolean executeCompensateMethod(String json) { JSONObject jsonObject = JSON.parseObject(json); String model = jsonObject.getString("model"); diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/manager/service/impl/TxManagerSenderServiceImpl.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/manager/service/impl/TxManagerSenderServiceImpl.java index c2b781ab5..8894fb1b0 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/manager/service/impl/TxManagerSenderServiceImpl.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/manager/service/impl/TxManagerSenderServiceImpl.java @@ -301,19 +301,11 @@ public class TxManagerSenderServiceImpl implements TxManagerSenderService { private ScheduledFuture schedule(final String key, int delayTime) { - ScheduledFuture future = executorService.schedule(new Runnable() { - @Override - public void run() { - Task task = ConditionUtils.getInstance().getTask(key); - if (task != null && !task.isNotify()) { - task.setBack(new IBack() { - @Override - public Object doing(Object... objs) throws Throwable { - return "-2"; - } - }); - task.signalTask(); - } + ScheduledFuture future = executorService.schedule(() -> { + Task task = ConditionUtils.getInstance().getTask(key); + if (task != null && !task.isNotify()) { + task.setBack(objs -> "-2"); + task.signalTask(); } }, delayTime, TimeUnit.SECONDS); diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/model/ChannelSender.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/model/ChannelSender.java index 476f4c57e..3e399334c 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/model/ChannelSender.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/model/ChannelSender.java @@ -64,22 +64,12 @@ public class ChannelSender { final String res = HttpUtils.post(url, "msg=" + msg + "&model=" + modelName); if (StringUtils.isNotEmpty(res)) { if (task != null) { - task.setBack(new IBack() { - @Override - public Object doing(Object... objs) throws Throwable { - return res; - } - }); + task.setBack(objs -> res); task.signalTask(); } } else { if (task != null) { - task.setBack(new IBack() { - @Override - public Object doing(Object... objs) throws Throwable { - return "-2"; - } - }); + task.setBack(objs -> "-2"); task.signalTask(); } } diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/handler/TxCoreServerHandler.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/handler/TxCoreServerHandler.java index 64b4e0dff..1ee5e11d8 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/handler/TxCoreServerHandler.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/handler/TxCoreServerHandler.java @@ -32,6 +32,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; +import lombok.SneakyThrows; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,15 +63,10 @@ public class TxCoreServerHandler extends ChannelInboundHandlerAdapter { // (1) } @Override - public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { + public void channelRead(final ChannelHandlerContext ctx, Object msg) { final String json = SocketUtils.getJson(msg); logger.debug("request->" + json); - threadPool.execute(new Runnable() { - @Override - public void run() { - service(json, ctx); - } - }); + threadPool.execute(() -> service(json, ctx)); } private void service(String json, ChannelHandlerContext ctx) { @@ -95,7 +91,8 @@ public class TxCoreServerHandler extends ChannelInboundHandlerAdapter { // (1) } @Override - public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + @SneakyThrows + public void channelRegistered(ChannelHandlerContext ctx) { //是否到达最大上线连接数 if (SocketManager.getInstance().isAllowConnection()) { @@ -107,7 +104,8 @@ public class TxCoreServerHandler extends ChannelInboundHandlerAdapter { // (1) } @Override - public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + @SneakyThrows + public void channelUnregistered(ChannelHandlerContext ctx) { SocketManager.getInstance().removeClient(ctx.channel()); String modelName = ctx.channel().remoteAddress().toString(); @@ -118,18 +116,18 @@ public class TxCoreServerHandler extends ChannelInboundHandlerAdapter { // (1) } @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); //ctx.close(); } @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { //心跳配置 if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) { IdleStateEvent event = (IdleStateEvent) evt; diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/BaseSignalTaskService.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/BaseSignalTaskService.java index 56237aeb1..28049be62 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/BaseSignalTaskService.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/BaseSignalTaskService.java @@ -32,12 +32,7 @@ public class BaseSignalTaskService { final String data = params.getString("d"); Task task = ConditionUtils.getInstance().getTask(key); if (task != null) { - task.setBack(new IBack() { - @Override - public Object doing(Object... objs) throws Throwable { - return data; - } - }); + task.setBack(objs -> data); task.signalTask(); } return res; diff --git a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/NettyServerServiceImpl.java b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/NettyServerServiceImpl.java index 49e02ee87..5c3525096 100644 --- a/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/NettyServerServiceImpl.java +++ b/pigx-visual/pigx-tx-manager/src/main/java/com/pig4cloud/pigx/manager/netty/service/impl/NettyServerServiceImpl.java @@ -81,7 +81,7 @@ public class NettyServerServiceImpl implements NettyServerService, DisposableBea .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer() { @Override - public void initChannel(SocketChannel ch) throws Exception { + public void initChannel(SocketChannel ch) { ch.pipeline().addLast("timeout", new IdleStateHandler(heartTime, heartTime, heartTime, TimeUnit.SECONDS)); ch.pipeline().addLast(new LengthFieldPrepender(4, false)); @@ -113,7 +113,7 @@ public class NettyServerServiceImpl implements NettyServerService, DisposableBea } @Override - public void destroy() throws Exception { + public void destroy() { close(); threadPool.shutdown(); }