diff --git a/pom.xml b/pom.xml index e8c2bac4e..657c77a1f 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,7 @@ 2.5.11 2.3.4 + 0.16.0 3.14.0 @@ -376,6 +377,12 @@ ${rocketmq.version} + + org.apache.fory + fory-core + ${fory.version} + + org.dromara.warm diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index 8b5f0b9e4..f827b1f1f 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -22,4 +22,11 @@ ruoyi-api系统接口 + + + org.springframework.cloud + spring-cloud-openfeign-core + + + diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java index 3f94c8cf4..e1e7c754e 100644 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java @@ -1,13 +1,15 @@ package org.dromara.resource.api; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.annotation.RemoteHttpService; import org.dromara.resource.api.domain.RemoteFile; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.List; @@ -16,8 +18,8 @@ import java.util.List; * * @author Lion Li */ -@RemoteHttpService(value = "ruoyi-resource", fallback = RemoteFileServiceFallback.class) -@HttpExchange("/remote/file") +@FeignClient(contextId = "remoteFileService", name = "ruoyi-resource", path = "/remote/file", + fallbackFactory = RemoteFileServiceFallbackFactory.class, primary = false) public interface RemoteFileService { /** @@ -26,7 +28,7 @@ public interface RemoteFileService { * @param file 文件信息 * @return 结果 */ - @PostExchange("/upload") + @PostMapping("/upload") RemoteFile upload(@RequestParam String name, @RequestParam String originalFilename, @RequestParam String contentType, @RequestBody byte[] file) throws ServiceException; @@ -36,7 +38,7 @@ public interface RemoteFileService { * @param ossIds ossId串逗号分隔 * @return url串逗号分隔 */ - @GetExchange("/select-url-by-ids") + @GetMapping("/select-url-by-ids") String selectUrlByIds(@RequestParam String ossIds); /** @@ -45,6 +47,7 @@ public interface RemoteFileService { * @param ossIds ossId串逗号分隔 * @return 列表 */ - @GetExchange("/select-by-ids") + @GetMapping("/select-by-ids") List selectByIds(@RequestParam String ossIds); } + diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallback.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallback.java deleted file mode 100644 index 1e1de3beb..000000000 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallback.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.dromara.resource.api; - -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.resource.api.domain.RemoteFile; - -import java.util.List; - -/** - * 文件服务熔断降级. - * - * @author Lion Li - */ -@Slf4j -public class RemoteFileServiceFallback implements RemoteFileService { - - /** - * 上传文件 - * - * @param file 文件信息 - * @return 结果 - */ - @Override - public RemoteFile upload(String name, String originalFilename, String contentType, byte[] file) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - /** - * 通过ossId查询对应的url - * - * @param ossIds ossId串逗号分隔 - * @return url串逗号分隔 - */ - @Override - public String selectUrlByIds(String ossIds) { - log.warn("服务调用异常 -> 降级处理"); - return StringUtils.EMPTY; - } - - /** - * 通过ossId查询列表 - * - * @param ossIds ossId串逗号分隔 - * @return 列表 - */ - @Override - public List selectByIds(String ossIds) { - log.warn("服务调用异常 -> 降级处理"); - return List.of(); - } - -} diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallbackFactory.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallbackFactory.java new file mode 100644 index 000000000..99580dbc8 --- /dev/null +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceFallbackFactory.java @@ -0,0 +1,40 @@ +package org.dromara.resource.api; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.resource.api.domain.RemoteFile; +import org.springframework.cloud.openfeign.FallbackFactory; + +import java.util.List; + +/** + * 文件服务 fallback factory. + * + * @author Lion Li + */ +@Slf4j +public class RemoteFileServiceFallbackFactory implements FallbackFactory { + + @Override + public RemoteFileService create(Throwable cause) { + return new RemoteFileService() { + @Override + public RemoteFile upload(String name, String originalFilename, String contentType, byte[] file) { + log.warn("文件服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public String selectUrlByIds(String ossIds) { + log.warn("文件服务调用失败, 已触发 fallback", cause); + return StringUtils.EMPTY; + } + + @Override + public List selectByIds(String ossIds) { + log.warn("文件服务调用失败, 已触发 fallback", cause); + return List.of(); + } + }; + } +} diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMailService.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMailService.java index 207822973..1cf1c1e23 100644 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMailService.java +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMailService.java @@ -1,18 +1,17 @@ package org.dromara.resource.api; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.annotation.RemoteHttpService; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; /** * 邮件服务 * * @author Lion Li */ -@RemoteHttpService("ruoyi-resource") -@HttpExchange("/remote/mail") +@FeignClient(contextId = "remoteMailService", name = "ruoyi-resource", path = "/remote/mail", primary = false) public interface RemoteMailService { /** @@ -22,7 +21,9 @@ public interface RemoteMailService { * @param subject 标题 * @param text 内容 */ - @PostExchange("/send") + @PostMapping("/send") void send(@RequestParam String to, @RequestParam String subject, @RequestParam String text) throws ServiceException; } + + diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageService.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageService.java index 0fa88bb41..d4cc58ad1 100644 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageService.java +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageService.java @@ -1,10 +1,13 @@ package org.dromara.resource.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.List; @@ -13,8 +16,8 @@ import java.util.List; * * @author Lion Li */ -@RemoteHttpService(value = "ruoyi-resource", fallback = RemoteMessageServiceFallback.class) -@HttpExchange("/remote/message") +@FeignClient(contextId = "remoteMessageService", name = "ruoyi-resource", path = "/remote/message", + fallbackFactory = RemoteMessageServiceFallbackFactory.class, primary = false) public interface RemoteMessageService { /** @@ -23,7 +26,7 @@ public interface RemoteMessageService { * @param sessionKey session主键 一般为用户id * @param message 消息文本 */ - @PostExchange("/publish-message") + @PostMapping("/publish-message") void publishMessage(@RequestBody List sessionKey, @RequestParam String message); /** @@ -31,6 +34,7 @@ public interface RemoteMessageService { * * @param message 消息内容 */ - @PostExchange("/publish-all") + @PostMapping("/publish-all") void publishAll(@RequestParam String message); } + diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallback.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallback.java deleted file mode 100644 index 573515ac0..000000000 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallback.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.dromara.resource.api; - -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -/** - * 消息服务熔断降级. - * - * @author Lion Li - */ -@Slf4j -public class RemoteMessageServiceFallback implements RemoteMessageService { - - /** - * 发送消息 - * - * @param sessionKey session主键 一般为用户id - * @param message 消息文本 - */ - @Override - public void publishMessage(List sessionKey, String message) { - log.warn("消息服务调用失败, 已触发熔断降级"); - } - - /** - * 发布订阅的消息(群发) - * - * @param message 消息内容 - */ - @Override - public void publishAll(String message) { - log.warn("消息服务调用失败, 已触发熔断降级"); - } -} diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallbackFactory.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallbackFactory.java new file mode 100644 index 000000000..2aa97ceb2 --- /dev/null +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceFallbackFactory.java @@ -0,0 +1,30 @@ +package org.dromara.resource.api; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.openfeign.FallbackFactory; + +import java.util.List; + +/** + * 消息服务 fallback factory. + * + * @author Lion Li + */ +@Slf4j +public class RemoteMessageServiceFallbackFactory implements FallbackFactory { + + @Override + public RemoteMessageService create(Throwable cause) { + return new RemoteMessageService() { + @Override + public void publishMessage(List sessionKey, String message) { + log.warn("消息服务调用失败, 已触发 fallback", cause); + } + + @Override + public void publishAll(String message) { + log.warn("消息服务调用失败, 已触发 fallback", cause); + } + }; + } +} diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteSmsService.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteSmsService.java index c0a8e7d8b..1b17a763f 100644 --- a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteSmsService.java +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteSmsService.java @@ -1,13 +1,16 @@ package org.dromara.resource.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.resource.api.domain.RemoteSms; import org.dromara.resource.api.domain.RemoteSmsBatch; import org.dromara.resource.api.domain.RemoteSmsDelayBatch; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.LinkedHashMap; import java.util.List; @@ -17,8 +20,7 @@ import java.util.List; * * @author Feng */ -@RemoteHttpService("ruoyi-resource") -@HttpExchange("/inner/remote/resource/sms") +@FeignClient(contextId = "remoteSmsService", name = "ruoyi-resource", path = "/inner/remote/resource/sms", primary = false) public interface RemoteSmsService { /** @@ -28,7 +30,7 @@ public interface RemoteSmsService { * @param message 短信内容 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/send-text") + @PostMapping("/send-text") RemoteSms sendMessage(@RequestParam String phone, @RequestParam String message); /** @@ -38,7 +40,7 @@ public interface RemoteSmsService { * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/send-vars") + @PostMapping("/send-vars") RemoteSms sendMessage(@RequestParam String phone, @RequestBody LinkedHashMap messages); /** @@ -49,7 +51,7 @@ public interface RemoteSmsService { * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/send-template") + @PostMapping("/send-template") RemoteSms sendMessage(@RequestParam String phone, @RequestParam String templateId, @RequestBody LinkedHashMap messages); @@ -60,7 +62,7 @@ public interface RemoteSmsService { * @param message 短信内容 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/message-texting") + @PostMapping("/message-texting") RemoteSms messageTexting(@RequestBody List phones, @RequestParam String message); /** @@ -71,7 +73,7 @@ public interface RemoteSmsService { * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/message-texting-template") + @PostMapping("/message-texting-template") default RemoteSms messageTexting(List phones, String templateId, LinkedHashMap messages) { return messageTextingTemplate(new RemoteSmsBatch(phones, templateId, messages)); } @@ -82,7 +84,7 @@ public interface RemoteSmsService { * @param request 群发模板短信请求 * @return 封装了短信发送结果的 RemoteSms 对象 */ - @PostExchange("/message-texting-template") + @PostMapping("/message-texting-template") RemoteSms messageTextingTemplate(@RequestBody RemoteSmsBatch request); /** @@ -91,7 +93,7 @@ public interface RemoteSmsService { * @param phone 目标手机号 * @param message 短信内容 */ - @PostExchange("/send-async-text") + @PostMapping("/send-async-text") void sendMessageAsync(@RequestParam String phone, @RequestParam String message); /** @@ -101,7 +103,7 @@ public interface RemoteSmsService { * @param templateId 短信模板ID * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 */ - @PostExchange("/send-async-template") + @PostMapping("/send-async-template") void sendMessageAsync(@RequestParam String phone, @RequestParam String templateId, @RequestBody LinkedHashMap messages); @@ -112,7 +114,7 @@ public interface RemoteSmsService { * @param message 短信内容 * @param delayedTime 延迟发送时间(毫秒) */ - @PostExchange("/delay-text") + @PostMapping("/delay-text") void delayMessage(@RequestParam String phone, @RequestParam String message, @RequestParam Long delayedTime); /** @@ -123,7 +125,7 @@ public interface RemoteSmsService { * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 * @param delayedTime 延迟发送时间(毫秒) */ - @PostExchange("/delay-template") + @PostMapping("/delay-template") void delayMessage(@RequestParam String phone, @RequestParam String templateId, @RequestBody LinkedHashMap messages, @RequestParam Long delayedTime); @@ -134,7 +136,7 @@ public interface RemoteSmsService { * @param message 短信内容 * @param delayedTime 延迟发送时间(毫秒) */ - @PostExchange("/delay-message-texting") + @PostMapping("/delay-message-texting") void delayMessageTexting(@RequestBody List phones, @RequestParam String message, @RequestParam Long delayedTime); /** @@ -145,7 +147,7 @@ public interface RemoteSmsService { * @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序 * @param delayedTime 延迟发送时间(毫秒) */ - @PostExchange("/delay-message-texting-template") + @PostMapping("/delay-message-texting-template") default void delayMessageTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) { delayMessageTextingTemplate(new RemoteSmsDelayBatch(phones, templateId, messages, delayedTime)); @@ -156,7 +158,7 @@ public interface RemoteSmsService { * * @param request 延迟群发模板短信请求 */ - @PostExchange("/delay-message-texting-template") + @PostMapping("/delay-message-texting-template") void delayMessageTextingTemplate(@RequestBody RemoteSmsDelayBatch request); /** @@ -164,7 +166,7 @@ public interface RemoteSmsService { * * @param phone 手机号 */ - @PostExchange("/add-blacklist-one") + @PostMapping("/add-blacklist-one") void addBlacklist(@RequestParam String phone); /** @@ -172,7 +174,7 @@ public interface RemoteSmsService { * * @param phones 手机号列表 */ - @PostExchange("/add-blacklist-list") + @PostMapping("/add-blacklist-list") void addBlacklist(@RequestBody List phones); /** @@ -180,7 +182,7 @@ public interface RemoteSmsService { * * @param phone 手机号 */ - @PostExchange("/remove-blacklist-one") + @PostMapping("/remove-blacklist-one") void removeBlacklist(@RequestParam String phone); /** @@ -188,7 +190,8 @@ public interface RemoteSmsService { * * @param phones 手机号 */ - @PostExchange("/remove-blacklist-list") + @PostMapping("/remove-blacklist-list") void removeBlacklist(@RequestBody List phones); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteClientService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteClientService.java index 4769e8f73..54a5076ab 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteClientService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteClientService.java @@ -1,18 +1,20 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.vo.RemoteClientVo; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; /** * 客户端服务 * * @author Michelle.Chung */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/client") +@FeignClient(contextId = "remoteClientService", name = "ruoyi-system", path = "/remote/client", primary = false) public interface RemoteClientService { /** @@ -21,7 +23,8 @@ public interface RemoteClientService { * @param clientId 客户端id * @return 客户端对象 */ - @GetExchange("/query-by-client-id") + @GetMapping("/query-by-client-id") RemoteClientVo queryByClientId(@RequestParam String clientId); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java index 787360ba3..ede1c82c9 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteConfigService.java @@ -1,12 +1,15 @@ package org.dromara.system.api; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Dict; -import org.dromara.common.core.annotation.RemoteHttpService; import org.dromara.common.json.utils.JsonUtils; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; import java.math.BigDecimal; import java.util.List; @@ -16,15 +19,14 @@ import java.util.List; * * @author Michelle.Chung */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/config") +@FeignClient(contextId = "remoteConfigService", name = "ruoyi-system", path = "/remote/config", primary = false) public interface RemoteConfigService { /** * 获取注册开关 * @return true开启,false关闭 */ - @GetExchange("/select-register-enabled") + @GetMapping("/select-register-enabled") boolean selectRegisterEnabled(); /** @@ -33,7 +35,7 @@ public interface RemoteConfigService { * @param configKey 参数 key * @return 参数值 */ - @GetExchange("/get-config-value") + @GetMapping("/get-config-value") String getConfigValue(@RequestParam String configKey); /** @@ -121,3 +123,4 @@ public interface RemoteConfigService { } } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDataScopeService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDataScopeService.java index 710174640..16a4b0d6a 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDataScopeService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDataScopeService.java @@ -1,17 +1,19 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; /** * 数据权限服务 * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/data-scope") +@FeignClient(contextId = "remoteDataScopeService", name = "ruoyi-system", path = "/remote/data-scope", primary = false) public interface RemoteDataScopeService { /** @@ -20,7 +22,7 @@ public interface RemoteDataScopeService { * @param roleId 角色ID * @return 返回角色的自定义权限语句,如果没有找到则返回 null */ - @GetExchange("/role-custom") + @GetMapping("/role-custom") String getRoleCustom(@RequestParam Long roleId); /** @@ -29,7 +31,8 @@ public interface RemoteDataScopeService { * @param deptId 部门ID * @return 返回部门及其下级的权限语句,如果没有找到则返回 null */ - @GetExchange("/dept-and-child") + @GetMapping("/dept-and-child") String getDeptAndChild(@RequestParam Long deptId); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java index 248d332d1..00ecfa8de 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java @@ -1,12 +1,14 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.vo.RemoteDeptVo; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.Collection; import java.util.List; @@ -17,8 +19,7 @@ import java.util.Map; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/dept") +@FeignClient(contextId = "remoteDeptService", name = "ruoyi-system", path = "/remote/dept", primary = false) public interface RemoteDeptService { /** @@ -27,7 +28,7 @@ public interface RemoteDeptService { * @param deptIds 部门ID串逗号分隔 * @return 部门名称串逗号分隔 */ - @GetExchange("/select-dept-name-by-ids") + @GetMapping("/select-dept-name-by-ids") String selectDeptNameByIds(@RequestParam String deptIds); /** @@ -36,7 +37,7 @@ public interface RemoteDeptService { * @param deptId 部门ID,用于指定需要查询的部门 * @return 返回该部门的负责人ID */ - @GetExchange("/select-dept-leader-by-id") + @GetMapping("/select-dept-leader-by-id") Long selectDeptLeaderById(@RequestParam Long deptId); /** @@ -44,7 +45,7 @@ public interface RemoteDeptService { * * @return 部门列表 */ - @GetExchange("/select-depts-by-list") + @GetMapping("/select-depts-by-list") List selectDeptsByList(); /** @@ -53,7 +54,8 @@ public interface RemoteDeptService { * @param deptIds 部门 ID 列表 * @return Map,其中 key 为部门 ID,value 为对应的部门名称 */ - @PostExchange("/select-dept-names-by-ids") + @PostMapping("/select-dept-names-by-ids") Map selectDeptNamesByIds(@RequestBody Collection deptIds); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDictService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDictService.java index 1709158d5..49715f485 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDictService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDictService.java @@ -1,11 +1,14 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.vo.RemoteDictDataVo; import org.dromara.system.api.domain.vo.RemoteDictTypeVo; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; import java.util.List; @@ -14,8 +17,7 @@ import java.util.List; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/dict") +@FeignClient(contextId = "remoteDictService", name = "ruoyi-system", path = "/remote/dict", primary = false) public interface RemoteDictService { /** @@ -24,7 +26,7 @@ public interface RemoteDictService { * @param dictType 字典类型 * @return 字典类型 */ - @GetExchange("/select-dict-type-by-type") + @GetMapping("/select-dict-type-by-type") RemoteDictTypeVo selectDictTypeByType(@RequestParam String dictType); /** @@ -33,7 +35,8 @@ public interface RemoteDictService { * @param dictType 字典类型 * @return 字典数据集合信息 */ - @GetExchange("/select-dict-data-by-type") + @GetMapping("/select-dict-data-by-type") List selectDictDataByType(@RequestParam String dictType); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteLogService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteLogService.java index 2d9f498e2..acf60c059 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteLogService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteLogService.java @@ -1,19 +1,21 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.bo.RemoteLoginInfoBo; import org.dromara.system.api.domain.bo.RemoteOperLogBo; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; /** * 日志服务 * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/log") +@FeignClient(contextId = "remoteLogService", name = "ruoyi-system", path = "/remote/log", primary = false) public interface RemoteLogService { /** @@ -21,7 +23,7 @@ public interface RemoteLogService { * * @param sysOperLog 日志实体 */ - @PostExchange("/save-log") + @PostMapping("/save-log") void saveLog(@RequestBody RemoteOperLogBo sysOperLog); /** @@ -29,7 +31,8 @@ public interface RemoteLogService { * * @param sysLoginInfo 访问实体 */ - @PostExchange("/save-login-info") + @PostMapping("/save-login-info") void saveLoginInfo(@RequestBody RemoteLoginInfoBo sysLoginInfo); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePermissionService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePermissionService.java index d90aa9c4e..0f2548c72 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePermissionService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePermissionService.java @@ -1,9 +1,12 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; import java.util.Set; @@ -12,8 +15,7 @@ import java.util.Set; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/permission") +@FeignClient(contextId = "remotePermissionService", name = "ruoyi-system", path = "/remote/permission", primary = false) public interface RemotePermissionService { /** @@ -22,7 +24,7 @@ public interface RemotePermissionService { * @param userId 用户id * @return 角色权限信息 */ - @GetExchange("/role-permission") + @GetMapping("/role-permission") Set getRolePermission(@RequestParam Long userId); /** @@ -31,7 +33,8 @@ public interface RemotePermissionService { * @param userId 用户id * @return 菜单权限信息 */ - @GetExchange("/menu-permission") + @GetMapping("/menu-permission") Set getMenuPermission(@RequestParam Long userId); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePostService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePostService.java index 22b1c4b07..5a2f348cd 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePostService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemotePostService.java @@ -1,9 +1,12 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.Collection; import java.util.Map; @@ -13,8 +16,7 @@ import java.util.Map; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/post") +@FeignClient(contextId = "remotePostService", name = "ruoyi-system", path = "/remote/post", primary = false) public interface RemotePostService { /** @@ -23,7 +25,8 @@ public interface RemotePostService { * @param postIds 岗位 ID 列表 * @return Map,其中 key 为岗位 ID,value 为对应的岗位名称 */ - @PostExchange("/select-post-names-by-ids") + @PostMapping("/select-post-names-by-ids") Map selectPostNamesByIds(@RequestBody Collection postIds); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteRoleService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteRoleService.java index 7ece23310..aaad9740e 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteRoleService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteRoleService.java @@ -1,9 +1,12 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.Collection; import java.util.Map; @@ -13,8 +16,7 @@ import java.util.Map; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/role") +@FeignClient(contextId = "remoteRoleService", name = "ruoyi-system", path = "/remote/role", primary = false) public interface RemoteRoleService { /** @@ -23,7 +25,8 @@ public interface RemoteRoleService { * @param roleIds 角色 ID 列表 * @return Map,其中 key 为角色 ID,value 为对应的角色名称 */ - @PostExchange("/select-role-names-by-ids") + @PostMapping("/select-role-names-by-ids") Map selectRoleNamesByIds(@RequestBody Collection roleIds); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java index 2b236e671..32fd6b1c4 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java @@ -1,13 +1,15 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.bo.RemoteSocialBo; import org.dromara.system.api.domain.vo.RemoteSocialVo; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.List; @@ -16,8 +18,7 @@ import java.util.List; * * @author Michelle.Chung */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/social") +@FeignClient(contextId = "remoteSocialService", name = "ruoyi-system", path = "/remote/social", primary = false) public interface RemoteSocialService { /** @@ -26,7 +27,7 @@ public interface RemoteSocialService { * @param authId 认证id * @return 授权信息 */ - @GetExchange("/select-by-auth-id") + @GetMapping("/select-by-auth-id") List selectByAuthId(@RequestParam String authId); /** @@ -34,7 +35,7 @@ public interface RemoteSocialService { * * @param bo 社会化关系业务对象 */ - @PostExchange("/query-list") + @PostMapping("/query-list") List queryList(@RequestBody RemoteSocialBo bo); /** @@ -42,7 +43,7 @@ public interface RemoteSocialService { * * @param bo 社会化关系业务对象 */ - @PostExchange("/insert-by-bo") + @PostMapping("/insert-by-bo") void insertByBo(@RequestBody RemoteSocialBo bo); /** @@ -50,7 +51,7 @@ public interface RemoteSocialService { * * @param bo 社会化关系业务对象 */ - @PostExchange("/update-by-bo") + @PostMapping("/update-by-bo") void updateByBo(@RequestBody RemoteSocialBo bo); /** @@ -59,7 +60,8 @@ public interface RemoteSocialService { * @param socialId 社会化关系ID * @return 结果 */ - @PostExchange("/delete-with-valid-by-id") + @PostMapping("/delete-with-valid-by-id") Boolean deleteWithValidById(@RequestParam Long socialId); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteTaskAssigneeService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteTaskAssigneeService.java index 4c44181a0..bd2406aad 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteTaskAssigneeService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteTaskAssigneeService.java @@ -1,19 +1,21 @@ package org.dromara.system.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.system.api.domain.bo.RemoteTaskAssigneeBo; import org.dromara.system.api.domain.vo.RemoteTaskAssigneeVo; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; /** * 工作流设计器获取任务执行人 * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/task-assignee") +@FeignClient(contextId = "remoteTaskAssigneeService", name = "ruoyi-system", path = "/remote/task-assignee", primary = false) public interface RemoteTaskAssigneeService { /** @@ -22,7 +24,7 @@ public interface RemoteTaskAssigneeService { * @param taskQuery 查询条件 * @return 办理人 */ - @PostExchange("/select-roles") + @PostMapping("/select-roles") RemoteTaskAssigneeVo selectRolesByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery); /** @@ -31,7 +33,7 @@ public interface RemoteTaskAssigneeService { * @param taskQuery 查询条件 * @return 办理人 */ - @PostExchange("/select-posts") + @PostMapping("/select-posts") RemoteTaskAssigneeVo selectPostsByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery); /** @@ -40,7 +42,7 @@ public interface RemoteTaskAssigneeService { * @param taskQuery 查询条件 * @return 办理人 */ - @PostExchange("/select-depts") + @PostMapping("/select-depts") RemoteTaskAssigneeVo selectDeptsByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery); /** @@ -49,7 +51,8 @@ public interface RemoteTaskAssigneeService { * @param taskQuery 查询条件 * @return 办理人 */ - @PostExchange("/select-users") + @PostMapping("/select-users") RemoteTaskAssigneeVo selectUsersByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery); } + diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java index ca7684b21..8ae2da781 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java @@ -1,17 +1,19 @@ package org.dromara.system.api; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.user.UserException; -import org.dromara.common.core.annotation.RemoteHttpService; import org.dromara.system.api.domain.bo.RemoteUserBo; import org.dromara.system.api.domain.vo.RemoteUserVo; import org.dromara.system.api.model.LoginUser; import org.dromara.system.api.model.XcxLoginUser; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.Collection; import java.util.List; @@ -22,8 +24,7 @@ import java.util.Map; * * @author Lion Li */ -@RemoteHttpService("ruoyi-system") -@HttpExchange("/remote/user") +@FeignClient(contextId = "remoteUserService", name = "ruoyi-system", path = "/remote/user", primary = false) public interface RemoteUserService { /** @@ -32,7 +33,7 @@ public interface RemoteUserService { * @param username 用户名 * @return 结果 */ - @GetExchange("/get-by-username") + @GetMapping("/get-by-username") LoginUser getUserInfo(@RequestParam String username) throws UserException; /** @@ -41,7 +42,7 @@ public interface RemoteUserService { * @param userId 用户id * @return 结果 */ - @GetExchange("/get-by-id") + @GetMapping("/get-by-id") LoginUser getUserInfo(@RequestParam Long userId) throws UserException; /** @@ -50,7 +51,7 @@ public interface RemoteUserService { * @param phonenumber 手机号 * @return 结果 */ - @GetExchange("/get-by-phonenumber") + @GetMapping("/get-by-phonenumber") LoginUser getUserInfoByPhonenumber(@RequestParam String phonenumber) throws UserException; /** @@ -59,7 +60,7 @@ public interface RemoteUserService { * @param email 邮箱 * @return 结果 */ - @GetExchange("/get-by-email") + @GetMapping("/get-by-email") LoginUser getUserInfoByEmail(@RequestParam String email) throws UserException; /** @@ -68,7 +69,7 @@ public interface RemoteUserService { * @param openid openid * @return 结果 */ - @GetExchange("/get-by-openid") + @GetMapping("/get-by-openid") XcxLoginUser getUserInfoByOpenid(@RequestParam String openid) throws UserException; /** @@ -77,7 +78,7 @@ public interface RemoteUserService { * @param remoteUserBo 用户信息 * @return 结果 */ - @PostExchange("/register-user-info") + @PostMapping("/register-user-info") Boolean registerUserInfo(@RequestBody RemoteUserBo remoteUserBo) throws UserException, ServiceException; /** @@ -86,7 +87,7 @@ public interface RemoteUserService { * @param userId 用户id * @return 结果 */ - @GetExchange("/select-username-by-id") + @GetMapping("/select-username-by-id") String selectUserNameById(@RequestParam Long userId); /** @@ -95,7 +96,7 @@ public interface RemoteUserService { * @param userId 用户ID * @return 用户昵称 */ - @GetExchange("/select-nickname-by-id") + @GetMapping("/select-nickname-by-id") String selectNicknameById(@RequestParam Long userId); /** @@ -104,7 +105,7 @@ public interface RemoteUserService { * @param userIds 用户ID 多个用逗号隔开 * @return 用户昵称 */ - @GetExchange("/select-nickname-by-ids") + @GetMapping("/select-nickname-by-ids") String selectNicknameByIds(@RequestParam String userIds); /** @@ -113,7 +114,7 @@ public interface RemoteUserService { * @param userId 用户id * @return 用户手机号 */ - @GetExchange("/select-phonenumber-by-id") + @GetMapping("/select-phonenumber-by-id") String selectPhonenumberById(@RequestParam Long userId); /** @@ -122,7 +123,7 @@ public interface RemoteUserService { * @param userId 用户id * @return 用户邮箱 */ - @GetExchange("/select-email-by-id") + @GetMapping("/select-email-by-id") String selectEmailById(@RequestParam Long userId); /** @@ -131,7 +132,7 @@ public interface RemoteUserService { * @param userId 用户ID * @param ip IP地址 */ - @PostExchange("/record-login-info") + @PostMapping("/record-login-info") void recordLoginInfo(@RequestParam Long userId, @RequestParam String ip); /** @@ -140,7 +141,7 @@ public interface RemoteUserService { * @param userIds 用户ids * @return 用户列表 */ - @PostExchange("/select-list-by-ids") + @PostMapping("/select-list-by-ids") List selectListByIds(@RequestBody Collection userIds); /** @@ -149,7 +150,7 @@ public interface RemoteUserService { * @param roleIds 角色ids * @return 用户ids */ - @PostExchange("/select-user-ids-by-role-ids") + @PostMapping("/select-user-ids-by-role-ids") List selectUserIdsByRoleIds(@RequestBody Collection roleIds); /** @@ -158,7 +159,7 @@ public interface RemoteUserService { * @param roleIds 角色ids * @return 用户 */ - @PostExchange("/select-users-by-role-ids") + @PostMapping("/select-users-by-role-ids") List selectUsersByRoleIds(@RequestBody Collection roleIds); /** @@ -167,7 +168,7 @@ public interface RemoteUserService { * @param deptIds 部门ids * @return 用户 */ - @PostExchange("/select-users-by-dept-ids") + @PostMapping("/select-users-by-dept-ids") List selectUsersByDeptIds(@RequestBody Collection deptIds); /** @@ -176,7 +177,7 @@ public interface RemoteUserService { * @param postIds 岗位ids * @return 用户 */ - @PostExchange("/select-users-by-post-ids") + @PostMapping("/select-users-by-post-ids") List selectUsersByPostIds(@RequestBody Collection postIds); /** @@ -185,7 +186,8 @@ public interface RemoteUserService { * @param userIds 用户 ID 列表 * @return Map,其中 key 为用户 ID,value 为对应的用户昵称 */ - @PostExchange("/select-user-nicks-by-ids") + @PostMapping("/select-user-nicks-by-ids") Map selectUserNicksByIds(@RequestBody Collection userIds); } + diff --git a/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowService.java b/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowService.java index 6dfbbfe9c..e21fc3c37 100644 --- a/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowService.java +++ b/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowService.java @@ -1,14 +1,16 @@ package org.dromara.workflow.api; -import org.dromara.common.core.annotation.RemoteHttpService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.dromara.workflow.api.domain.RemoteCompleteTask; import org.dromara.workflow.api.domain.RemoteStartProcess; import org.dromara.workflow.api.domain.RemoteStartProcessReturn; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.annotation.PostExchange; import java.util.List; import java.util.Map; @@ -19,8 +21,8 @@ import java.util.Map; * @Author ZETA * @Date 2024/6/3 */ -@RemoteHttpService(value = "ruoyi-workflow", fallback = RemoteWorkflowServiceFallback.class) -@HttpExchange("/remote/workflow") +@FeignClient(contextId = "remoteWorkflowService", name = "ruoyi-workflow", path = "/remote/workflow", + fallbackFactory = RemoteWorkflowServiceFallbackFactory.class, primary = false) public interface RemoteWorkflowService { /** @@ -29,7 +31,7 @@ public interface RemoteWorkflowService { * @param businessIds 业务id * @return 结果 */ - @PostExchange("/delete-instance") + @PostMapping("/delete-instance") boolean deleteInstance(@RequestBody List businessIds); /** @@ -38,7 +40,7 @@ public interface RemoteWorkflowService { * @param taskId 任务id * @return 状态 */ - @GetExchange("/business-status-by-task-id") + @GetMapping("/business-status-by-task-id") String getBusinessStatusByTaskId(@RequestParam Long taskId); /** @@ -47,7 +49,7 @@ public interface RemoteWorkflowService { * @param businessId 业务id * @return 状态 */ - @GetExchange("/business-status") + @GetMapping("/business-status") String getBusinessStatus(@RequestParam String businessId); /** @@ -56,7 +58,7 @@ public interface RemoteWorkflowService { * @param instanceId 流程实例id * @param variable 流程变量 */ - @PostExchange("/set-variable") + @PostMapping("/set-variable") void setVariable(@RequestParam Long instanceId, @RequestBody Map variable); /** @@ -64,7 +66,7 @@ public interface RemoteWorkflowService { * * @param instanceId 流程实例id */ - @GetExchange("/instance-variable") + @GetMapping("/instance-variable") Map instanceVariable(@RequestParam Long instanceId); /** @@ -73,7 +75,7 @@ public interface RemoteWorkflowService { * @param businessId 业务id * @return 结果 */ - @GetExchange("/instance-id-by-business-id") + @GetMapping("/instance-id-by-business-id") Long getInstanceIdByBusinessId(@RequestParam String businessId); /** @@ -82,7 +84,7 @@ public interface RemoteWorkflowService { * @param startProcess 参数 * @return 结果 */ - @PostExchange("/start-workflow") + @PostMapping("/start-workflow") RemoteStartProcessReturn startWorkFlow(@RequestBody RemoteStartProcess startProcess); /** @@ -91,7 +93,7 @@ public interface RemoteWorkflowService { * @param completeTask 参数 * @return 结果 */ - @PostExchange("/complete-task") + @PostMapping("/complete-task") boolean completeTask(@RequestBody RemoteCompleteTask completeTask); @@ -102,7 +104,7 @@ public interface RemoteWorkflowService { * @param message 办理意见 * @return 结果 */ - @PostExchange("/complete-task-simple") + @PostMapping("/complete-task-simple") boolean completeTask(@RequestParam Long taskId, @RequestParam String message); /** @@ -111,7 +113,8 @@ public interface RemoteWorkflowService { * @param startProcess 参数 * @return 结果 */ - @PostExchange("/start-complete-task") + @PostMapping("/start-complete-task") boolean startCompleteTask(@RequestBody RemoteStartProcess startProcess); } + diff --git a/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallback.java b/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallback.java deleted file mode 100644 index 4caf87815..000000000 --- a/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallback.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.dromara.workflow.api; - -import lombok.extern.slf4j.Slf4j; -import org.dromara.workflow.api.domain.RemoteCompleteTask; -import org.dromara.workflow.api.domain.RemoteStartProcess; -import org.dromara.workflow.api.domain.RemoteStartProcessReturn; - -import java.util.List; -import java.util.Map; - -/** - * 工作流服务熔断降级. - * - * @author Lion Li - */ -@Slf4j -public class RemoteWorkflowServiceFallback implements RemoteWorkflowService { - - @Override - public boolean deleteInstance(List businessIds) { - log.warn("服务调用异常 -> 降级处理"); - return false; - } - - @Override - public String getBusinessStatusByTaskId(Long taskId) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - @Override - public String getBusinessStatus(String businessId) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - @Override - public void setVariable(Long instanceId, Map variable) { - log.warn("服务调用异常 -> 降级处理"); - } - - @Override - public Map instanceVariable(Long instanceId) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - @Override - public Long getInstanceIdByBusinessId(String businessId) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - @Override - public RemoteStartProcessReturn startWorkFlow(RemoteStartProcess startProcess) { - log.warn("服务调用异常 -> 降级处理"); - return null; - } - - @Override - public boolean completeTask(RemoteCompleteTask completeTask) { - log.warn("服务调用异常 -> 降级处理"); - return false; - } - - @Override - public boolean completeTask(Long taskId, String message) { - log.warn("服务调用异常 -> 降级处理"); - return false; - } - - @Override - public boolean startCompleteTask(RemoteStartProcess startProcess) { - log.warn("服务调用异常 -> 降级处理"); - return false; - } - -} diff --git a/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallbackFactory.java b/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallbackFactory.java new file mode 100644 index 000000000..b2d7495fc --- /dev/null +++ b/ruoyi-api/ruoyi-api-workflow/src/main/java/org/dromara/workflow/api/RemoteWorkflowServiceFallbackFactory.java @@ -0,0 +1,83 @@ +package org.dromara.workflow.api; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.workflow.api.domain.RemoteCompleteTask; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.domain.RemoteStartProcessReturn; +import org.springframework.cloud.openfeign.FallbackFactory; + +import java.util.List; +import java.util.Map; + +/** + * 工作流服务 fallback factory. + * + * @author Lion Li + */ +@Slf4j +public class RemoteWorkflowServiceFallbackFactory implements FallbackFactory { + + @Override + public RemoteWorkflowService create(Throwable cause) { + return new RemoteWorkflowService() { + @Override + public boolean deleteInstance(List businessIds) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return false; + } + + @Override + public String getBusinessStatusByTaskId(Long taskId) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public String getBusinessStatus(String businessId) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public void setVariable(Long instanceId, Map variable) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + } + + @Override + public Map instanceVariable(Long instanceId) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public Long getInstanceIdByBusinessId(String businessId) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public RemoteStartProcessReturn startWorkFlow(RemoteStartProcess startProcess) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return null; + } + + @Override + public boolean completeTask(RemoteCompleteTask completeTask) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return false; + } + + @Override + public boolean completeTask(Long taskId, String message) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return false; + } + + @Override + public boolean startCompleteTask(RemoteStartProcess startProcess) { + log.warn("工作流服务调用失败, 已触发 fallback", cause); + return false; + } + }; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/annotation/RemoteHttpService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/annotation/RemoteHttpService.java deleted file mode 100644 index a9350856f..000000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/annotation/RemoteHttpService.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.dromara.common.core.annotation; - -import org.springframework.core.annotation.AliasFor; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 声明远程 HTTP Service 所属服务. - * - * @author Lion Li - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface RemoteHttpService { - - /** - * 服务名. - */ - @AliasFor("serviceId") - String value() default ""; - - /** - * 服务名. - */ - @AliasFor("value") - String serviceId() default ""; - - /** - * 远程调用失败时的 fallback 实现. - */ - Class fallback() default void.class; - -} diff --git a/ruoyi-common/ruoyi-common-http/pom.xml b/ruoyi-common/ruoyi-common-http/pom.xml index a7789a572..0207c7218 100644 --- a/ruoyi-common/ruoyi-common-http/pom.xml +++ b/ruoyi-common/ruoyi-common-http/pom.xml @@ -31,15 +31,32 @@ ruoyi-common-satoken + + org.dromara + ruoyi-common-mybatis + true + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + org.springframework.cloud spring-cloud-starter-loadbalancer - org.eclipse.jetty - jetty-client + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + + + org.apache.fory + fory-core + + diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/annotation/RemoteServiceController.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/annotation/RemoteServiceController.java index c13dab0bd..c398af5e3 100644 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/annotation/RemoteServiceController.java +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/annotation/RemoteServiceController.java @@ -1,7 +1,9 @@ package org.dromara.common.http.annotation; import org.springframework.core.annotation.AliasFor; +import org.springframework.context.annotation.Primary; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMapping; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -18,8 +20,13 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Documented @RestController +@RequestMapping +@Primary public @interface RemoteServiceController { @AliasFor(annotation = RestController.class, attribute = "value") String value() default ""; + + @AliasFor(annotation = RequestMapping.class, attribute = "path") + String[] path() default {}; } diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpAutoConfiguration.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpAutoConfiguration.java index de6d05170..fe94b0744 100644 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpAutoConfiguration.java +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpAutoConfiguration.java @@ -1,38 +1,35 @@ package org.dromara.common.http.config; import cn.dev33.satoken.same.SaSameUtil; +import feign.Logger; +import feign.RequestInterceptor; +import feign.Response; +import feign.codec.ErrorDecoder; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.utils.ServletUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.core.annotation.RemoteHttpService; import org.dromara.common.http.annotation.RemoteServiceController; import org.dromara.common.http.log.aspect.RemoteHttpProviderLogAspect; import org.dromara.common.http.handler.RemoteHttpExceptionHandler; -import org.dromara.common.http.properties.RemoteHttpProperties; -import org.dromara.common.http.registrar.RemoteHttpServiceRegistrar; -import org.dromara.common.http.support.RemoteHttpFallbackProxyPostProcessor; -import org.dromara.common.http.log.support.LoggingHttpExchangeAdapter; +import org.dromara.common.http.log.support.RemoteHttpFeignLogger; import org.dromara.common.http.log.support.RemoteHttpLogSupport; import org.dromara.common.json.utils.JsonUtils; +import org.dromara.common.core.utils.ServletUtils; +import org.dromara.common.core.utils.StringUtils; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.aop.framework.autoproxy.AutoProxyUtils; -import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Bean; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.util.StreamUtils; -import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -43,26 +40,24 @@ import java.nio.charset.StandardCharsets; * 这里把运行时几条链路接起来: * 1. Consumer 发请求前透传认证头和 Seata XID * 2. 远程非 2xx 响应统一转成 ServiceException - * 3. 打开请求日志时,为 consumer/provider 两侧挂日志能力 - * 4. 远程代理失败时按接口声明触发 fallback + * 3. 打开请求日志时,为 consumer/provider 两侧挂统一日志 * * @author Lion Li */ @Slf4j @AutoConfiguration -@Import(RemoteHttpServiceRegistrar.class) -@EnableConfigurationProperties(RemoteHttpProperties.class) +@EnableFeignClients(basePackages = "org.dromara") public class RemoteHttpAutoConfiguration { @Bean - public static BeanFactoryPostProcessor remoteHttpControllerProxyCompatibilityPostProcessor() { + public static BeanDefinitionRegistryPostProcessor remoteHttpControllerProxyCompatibilityPostProcessor() { return new RemoteHttpInfrastructurePostProcessor(); } - @Bean("remoteHttpHeaderInterceptor") - public ClientHttpRequestInterceptor remoteHttpHeaderInterceptor() { - return (request, body, execution) -> { - HttpHeaders headers = request.getHeaders(); + @Bean + public RequestInterceptor remoteHttpRequestInterceptor() { + return requestTemplate -> { + HttpHeaders headers = new HttpHeaders(); HttpServletRequest currentRequest = ServletUtils.getRequest(); if (currentRequest != null) { String authorization = currentRequest.getHeader(HttpHeaders.AUTHORIZATION); @@ -76,35 +71,29 @@ public class RemoteHttpAutoConfiguration { } catch (Exception ignored) { } relaySeataXid(headers); - return execution.execute(request, body); + headers.forEach((key, values) -> values.forEach(value -> requestTemplate.header(key, value))); }; } @Bean - public RestClientHttpServiceGroupConfigurer remoteHttpServiceGroupConfigurer( - ClientHttpRequestInterceptor remoteHttpHeaderInterceptor, + public Logger remoteHttpFeignLogger( RemoteHttpLogSupport remoteHttpLogSupport) { - return groups -> groups.forEachGroup((group, clientBuilder, proxyFactoryBuilder) -> { - clientBuilder.requestInterceptor(remoteHttpHeaderInterceptor) - // provider 侧远程接口异常会直接映射成非 2xx,这里只按 HTTP 状态处理即可。 - .defaultStatusHandler(HttpStatusCode::isError, (request, response) -> { - throwServiceException(response.getStatusCode().value(), response.getStatusText(), readResponseBody(response)); - }); - if (remoteHttpLogSupport.isEnabled()) { - // consumer 侧日志挂在 HttpExchangeAdapter 上,避免碰底层 body 重复读取问题。 - proxyFactoryBuilder.exchangeAdapterDecorator(adapter -> new LoggingHttpExchangeAdapter(adapter, remoteHttpLogSupport)); - } - }); + return new RemoteHttpFeignLogger(remoteHttpLogSupport); } @Bean - public RemoteHttpFallbackProxyPostProcessor remoteHttpFallbackProxyPostProcessor() { - return new RemoteHttpFallbackProxyPostProcessor(); + public Logger.Level remoteHttpFeignLoggerLevel() { + return Logger.Level.BASIC; } @Bean - public RemoteHttpLogSupport remoteHttpLogSupport(RemoteHttpProperties properties) { - return new RemoteHttpLogSupport(properties); + public ErrorDecoder remoteHttpErrorDecoder() { + return (methodKey, response) -> buildServiceException(response.status(), response.reason(), readResponseBody(response)); + } + + @Bean + public RemoteHttpLogSupport remoteHttpLogSupport() { + return new RemoteHttpLogSupport(); } @Bean @@ -133,50 +122,85 @@ public class RemoteHttpAutoConfiguration { } } - private String readResponseBody(org.springframework.http.client.ClientHttpResponse response) { + private String readResponseBody(Response response) { + if (response.body() == null) { + return null; + } try { - return StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8); + return StreamUtils.copyToString(response.body().asInputStream(), StandardCharsets.UTF_8); } catch (IOException e) { log.debug("read remote response body failed", e); return null; } } - private void throwServiceException(int statusCode, String statusText, String responseBody) { + private ServiceException buildServiceException(int statusCode, String statusText, String responseBody) { if (StringUtils.isNotBlank(responseBody) && JsonUtils.isJsonObject(responseBody)) { try { // 远程服务如果按 R 返回错误信息,优先还原成更友好的业务异常消息。 R result = JsonUtils.parseObject(responseBody, R.class); if (result != null && (result.getCode() == 0 || R.isSuccess(result))) { - return; + return new ServiceException(StringUtils.defaultIfBlank(statusText, "远程服务调用失败"), statusCode); } if (result != null && StringUtils.isNotBlank(result.getMsg())) { - throw new ServiceException(result.getMsg(), result.getCode()); + return new ServiceException(result.getMsg(), result.getCode()); } - } catch (ServiceException se) { - throw se; } catch (RuntimeException e) { log.debug("parse remote error body failed: {}", responseBody, e); } } String message = StringUtils.firstNonBlank(responseBody, statusText, "远程服务调用失败"); - throw new ServiceException(message, statusCode); + return new ServiceException(message, statusCode); } - private static final class RemoteHttpInfrastructurePostProcessor implements BeanFactoryPostProcessor { + private static final class RemoteHttpInfrastructurePostProcessor implements BeanDefinitionRegistryPostProcessor { + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { + for (String beanName : registry.getBeanDefinitionNames()) { + BeanDefinition beanDefinition = registry.getBeanDefinition(beanName); + registerFallbackBeanIfNecessary(registry, beanDefinition, "fallback"); + registerFallbackBeanIfNecessary(registry, beanDefinition, "fallbackFactory"); + } + } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { - BeanDefinitionRegistry registry = beanFactory instanceof BeanDefinitionRegistry beanDefinitionRegistry - ? beanDefinitionRegistry : null; - ClassLoader beanClassLoader = beanFactory.getBeanClassLoader(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); preserveRemoteControllerTargetClass(beanDefinition); - registerFallbackBeanDefinition(registry, beanFactory, beanDefinition, beanClassLoader); } } + private void registerFallbackBeanIfNecessary(BeanDefinitionRegistry registry, BeanDefinition beanDefinition, + String propertyName) { + if (!FeignClientFactoryBean.class.getName().equals(beanDefinition.getBeanClassName())) { + return; + } + Object propertyValue = beanDefinition.getPropertyValues().get(propertyName); + if (!(propertyValue instanceof Class fallbackType) || Object.class == fallbackType || void.class == fallbackType) { + return; + } + // fallback/fallbackFactory 常放在 api 模块里,默认应用包扫描不会覆盖到这里, + // 所以在 FeignClient 注册完成后顺手把它补成 Spring Bean。 + String fallbackBeanName = fallbackType.getName(); + if (registry.containsBeanDefinition(fallbackBeanName) || hasBeanClass(registry, fallbackType)) { + return; + } + registry.registerBeanDefinition(fallbackBeanName, + BeanDefinitionBuilder.genericBeanDefinition(fallbackType).getBeanDefinition()); + } + + private boolean hasBeanClass(BeanDefinitionRegistry registry, Class beanClass) { + for (String beanName : registry.getBeanDefinitionNames()) { + BeanDefinition candidate = registry.getBeanDefinition(beanName); + if (beanClass.getName().equals(candidate.getBeanClassName())) { + return true; + } + } + return false; + } + private void preserveRemoteControllerTargetClass(BeanDefinition beanDefinition) { if (!(beanDefinition instanceof AnnotatedBeanDefinition annotatedBeanDefinition)) { return; @@ -186,48 +210,5 @@ public class RemoteHttpAutoConfiguration { } beanDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); } - - private void registerFallbackBeanDefinition(BeanDefinitionRegistry registry, - ConfigurableListableBeanFactory beanFactory, BeanDefinition beanDefinition, ClassLoader beanClassLoader) { - if (registry == null) { - return; - } - Class serviceInterface = resolveRemoteServiceInterface(beanDefinition, beanClassLoader); - if (serviceInterface == null) { - return; - } - RemoteHttpService remoteHttpService = serviceInterface.getAnnotation(RemoteHttpService.class); - if (remoteHttpService == null || remoteHttpService.fallback() == void.class) { - return; - } - Class fallbackClass = remoteHttpService.fallback(); - if (!serviceInterface.isAssignableFrom(fallbackClass)) { - throw new IllegalStateException("Fallback class must implement remote service interface: " - + fallbackClass.getName() + " -> " + serviceInterface.getName()); - } - if (beanFactory.getBeanNamesForType(fallbackClass, false, false).length > 0) { - return; - } - BeanDefinition fallbackBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(fallbackClass) - .setLazyInit(true) - .getBeanDefinition(); - // fallback 只给框架内部按具体类型获取使用,不参与业务侧按接口类型自动注入, - // 否则会和真正的远程代理一起成为 RemoteXxxService 的候选 Bean。 - fallbackBeanDefinition.setAutowireCandidate(false); - fallbackBeanDefinition.setPrimary(false); - registry.registerBeanDefinition(fallbackClass.getName(), fallbackBeanDefinition); - } - - private Class resolveRemoteServiceInterface(BeanDefinition beanDefinition, ClassLoader beanClassLoader) { - String beanClassName = beanDefinition.getBeanClassName(); - if (beanClassName == null || beanClassLoader == null) { - return null; - } - Class beanClass = org.springframework.util.ClassUtils.resolveClassName(beanClassName, beanClassLoader); - if (!beanClass.isInterface() || !beanClass.isAnnotationPresent(RemoteHttpService.class)) { - return null; - } - return beanClass; - } } } diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpDataPermissionAutoConfiguration.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpDataPermissionAutoConfiguration.java new file mode 100644 index 000000000..6448bcaf2 --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/config/RemoteHttpDataPermissionAutoConfiguration.java @@ -0,0 +1,49 @@ +package org.dromara.common.http.config; + +import feign.RequestInterceptor; +import org.dromara.common.http.support.RemoteHttpDataPermissionCodec; +import org.dromara.common.http.support.RemoteHttpDataPermissionInterceptor; +import org.dromara.common.http.support.RemoteHttpDataPermissionRequestInterceptor; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 数据权限透传自动配置。 + * + * 仅在引入 ruoyi-common-mybatis 后生效。 + */ +@AutoConfiguration +@ConditionalOnClass(name = "org.dromara.common.mybatis.helper.DataPermissionHelper") +public class RemoteHttpDataPermissionAutoConfiguration { + + @Bean + public RemoteHttpDataPermissionCodec remoteHttpDataPermissionCodec() { + return new RemoteHttpDataPermissionCodec(); + } + + @Bean + public RequestInterceptor remoteHttpDataPermissionRequestInterceptor( + RemoteHttpDataPermissionCodec remoteHttpDataPermissionCodec) { + return new RemoteHttpDataPermissionRequestInterceptor(remoteHttpDataPermissionCodec); + } + + @Bean + public RemoteHttpDataPermissionInterceptor remoteHttpDataPermissionInterceptor( + RemoteHttpDataPermissionCodec remoteHttpDataPermissionCodec) { + return new RemoteHttpDataPermissionInterceptor(remoteHttpDataPermissionCodec); + } + + @Bean + public WebMvcConfigurer remoteHttpDataPermissionWebMvcConfigurer( + RemoteHttpDataPermissionInterceptor remoteHttpDataPermissionInterceptor) { + return new WebMvcConfigurer() { + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(remoteHttpDataPermissionInterceptor); + } + }; + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/aspect/RemoteHttpProviderLogAspect.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/aspect/RemoteHttpProviderLogAspect.java index 1ca4264d2..c95045dbe 100644 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/aspect/RemoteHttpProviderLogAspect.java +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/aspect/RemoteHttpProviderLogAspect.java @@ -1,19 +1,19 @@ package org.dromara.common.http.log.aspect; import jakarta.servlet.http.HttpServletRequest; +import org.springframework.cloud.openfeign.FeignClient; import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.dromara.common.core.utils.ServletUtils; -import org.dromara.common.core.annotation.RemoteHttpService; import org.dromara.common.http.log.support.RemoteHttpLogSupport; import org.springframework.http.HttpMethod; -import org.springframework.web.service.annotation.HttpExchange; import org.springframework.aop.support.AopUtils; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; @@ -40,9 +40,9 @@ public class RemoteHttpProviderLogAspect { HttpServletRequest request = ServletUtils.getRequest(); Class remoteInterface = resolveRemoteInterface(targetClass, method); // 真实 HTTP 调用时优先从 servlet 请求拿 method/path; - // 本地短路调用时再回退到接口上的 @HttpExchange 注解。 - HttpMethod httpMethod = resolveHttpMethod(request, remoteInterface, method); - String path = resolvePath(request, remoteInterface, method); + // 本地注入 provider bean 时再回退到接口上的 Spring MVC 映射注解。 + HttpMethod httpMethod = resolveHttpMethod(request, remoteInterface, targetClass, method); + String path = resolvePath(request, remoteInterface, targetClass, method); this.logSupport.logRequest(RemoteHttpLogSupport.PROVIDER, httpMethod, path, arguments); long startTime = System.currentTimeMillis(); try { @@ -55,22 +55,25 @@ public class RemoteHttpProviderLogAspect { } } - private HttpMethod resolveHttpMethod(HttpServletRequest request, Class remoteInterface, Method method) { + private HttpMethod resolveHttpMethod(HttpServletRequest request, Class remoteInterface, Class targetClass, Method method) { if (request != null && StringUtils.hasText(request.getMethod())) { return HttpMethod.valueOf(request.getMethod()); } - HttpExchange methodExchange = resolveMethodExchange(remoteInterface, method); - if (methodExchange != null && StringUtils.hasText(methodExchange.method())) { - return HttpMethod.valueOf(methodExchange.method()); + RequestMapping methodMapping = resolveMethodMapping(remoteInterface, method); + if (methodMapping != null && methodMapping.method().length > 0) { + return HttpMethod.valueOf(methodMapping.method()[0].name()); } - HttpExchange typeExchange = resolveTypeExchange(remoteInterface); - if (typeExchange != null && StringUtils.hasText(typeExchange.method())) { - return HttpMethod.valueOf(typeExchange.method()); + RequestMapping typeMapping = resolveTypeMapping(remoteInterface); + if (typeMapping == null) { + typeMapping = resolveTypeMapping(targetClass); + } + if (typeMapping != null && typeMapping.method().length > 0) { + return HttpMethod.valueOf(typeMapping.method()[0].name()); } return null; } - private String resolvePath(HttpServletRequest request, Class remoteInterface, Method method) { + private String resolvePath(HttpServletRequest request, Class remoteInterface, Class targetClass, Method method) { if (request != null) { String requestUri = request.getRequestURI(); if (StringUtils.hasText(requestUri)) { @@ -81,8 +84,11 @@ public class RemoteHttpProviderLogAspect { return requestUri + '?' + queryString; } } - String typePath = extractPath(resolveTypeExchange(remoteInterface)); - String methodPath = extractPath(resolveMethodExchange(remoteInterface, method)); + String typePath = extractPath(resolveTypeMapping(remoteInterface)); + if (!StringUtils.hasText(typePath)) { + typePath = extractPath(resolveTypeMapping(targetClass)); + } + String methodPath = extractPath(resolveMethodMapping(remoteInterface, method)); if (!StringUtils.hasText(typePath)) { return methodPath; } @@ -95,7 +101,7 @@ public class RemoteHttpProviderLogAspect { private Class resolveRemoteInterface(Class targetClass, Method method) { for (Class interfaceType : targetClass.getInterfaces()) { - if (interfaceType.isAnnotationPresent(RemoteHttpService.class) + if (interfaceType.isAnnotationPresent(FeignClient.class) && org.springframework.util.ReflectionUtils.findMethod(interfaceType, method.getName(), method.getParameterTypes()) != null) { return interfaceType; } @@ -103,14 +109,14 @@ public class RemoteHttpProviderLogAspect { return null; } - private HttpExchange resolveTypeExchange(Class remoteInterface) { + private RequestMapping resolveTypeMapping(Class remoteInterface) { if (remoteInterface == null) { return null; } - return AnnotatedElementUtils.findMergedAnnotation(remoteInterface, HttpExchange.class); + return AnnotatedElementUtils.findMergedAnnotation(remoteInterface, RequestMapping.class); } - private HttpExchange resolveMethodExchange(Class remoteInterface, Method method) { + private RequestMapping resolveMethodMapping(Class remoteInterface, Method method) { if (remoteInterface == null) { return null; } @@ -118,18 +124,18 @@ public class RemoteHttpProviderLogAspect { if (interfaceMethod == null) { return null; } - return AnnotatedElementUtils.findMergedAnnotation(interfaceMethod, HttpExchange.class); + return AnnotatedElementUtils.findMergedAnnotation(interfaceMethod, RequestMapping.class); } - private String extractPath(HttpExchange exchange) { - if (exchange == null) { + private String extractPath(RequestMapping mapping) { + if (mapping == null) { return null; } - if (StringUtils.hasText(exchange.url())) { - return exchange.url(); + if (mapping.path().length > 0 && StringUtils.hasText(mapping.path()[0])) { + return mapping.path()[0]; } - if (StringUtils.hasText(exchange.value())) { - return exchange.value(); + if (mapping.value().length > 0 && StringUtils.hasText(mapping.value()[0])) { + return mapping.value()[0]; } return null; } diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/enums/RequestLogEnum.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/enums/RequestLogEnum.java deleted file mode 100644 index b8d93b5d8..000000000 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/enums/RequestLogEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.dromara.common.http.log.enums; - -import lombok.AllArgsConstructor; - -/** - * 请求日志级别. - * - * @author Lion Li - */ -@AllArgsConstructor -public enum RequestLogEnum { - - /** - * 基础信息. - */ - INFO, - - /** - * 参数信息. - */ - PARAM, - - /** - * 全量信息. - */ - FULL - -} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/LoggingHttpExchangeAdapter.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/LoggingHttpExchangeAdapter.java deleted file mode 100644 index 87ed90360..000000000 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/LoggingHttpExchangeAdapter.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.dromara.common.http.log.support; - -import org.dromara.common.core.exception.ServiceException; -import org.jspecify.annotations.Nullable; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; -import org.springframework.web.service.invoker.HttpExchangeAdapter; -import org.springframework.web.service.invoker.HttpExchangeAdapterDecorator; -import org.springframework.web.service.invoker.HttpRequestValues; - -import java.net.URI; -import java.util.Map; - -/** - * 内部 HTTP Consumer 日志装饰器. - * - * Consumer 侧日志挂在 HttpServiceProxyFactory 的 exchange adapter 上, - * 这样可以直接拿到最终请求 method/path 和解码后的返回值, - * 比直接拦截底层流更稳定,也更容易规避 body 重复读问题。 - * - * @author Lion Li - */ -public class LoggingHttpExchangeAdapter extends HttpExchangeAdapterDecorator { - - private final RemoteHttpLogSupport logSupport; - - public LoggingHttpExchangeAdapter(HttpExchangeAdapter delegate, RemoteHttpLogSupport logSupport) { - super(delegate); - this.logSupport = logSupport; - } - - @Override - public void exchange(HttpRequestValues requestValues) { - invoke(requestValues, () -> { - super.exchange(requestValues); - return null; - }); - } - - @Override - public HttpHeaders exchangeForHeaders(HttpRequestValues requestValues) { - return invoke(requestValues, () -> super.exchangeForHeaders(requestValues)); - } - - @Override - public @Nullable T exchangeForBody(HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - return invoke(requestValues, () -> super.exchangeForBody(requestValues, bodyType)); - } - - @Override - public ResponseEntity exchangeForBodilessEntity(HttpRequestValues requestValues) { - return invoke(requestValues, () -> super.exchangeForBodilessEntity(requestValues)); - } - - @Override - public ResponseEntity exchangeForEntity(HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - return invoke(requestValues, () -> super.exchangeForEntity(requestValues, bodyType)); - } - - private T invoke(HttpRequestValues requestValues, ThrowingSupplier supplier) { - HttpMethod httpMethod = requestValues.getHttpMethod(); - String path = resolvePath(requestValues); - Object bodyValue = requestValues.getBodyValue(); - Object[] arguments = bodyValue == null ? new Object[0] : bodyValue instanceof Object[] array ? array : new Object[] {bodyValue}; - this.logSupport.logRequest(RemoteHttpLogSupport.CONSUMER, httpMethod, path, arguments); - long startTime = System.currentTimeMillis(); - try { - T result = supplier.get(); - this.logSupport.logResponse(RemoteHttpLogSupport.CONSUMER, httpMethod, path, - System.currentTimeMillis() - startTime, result); - return result; - } catch (Throwable ex) { - this.logSupport.logException(RemoteHttpLogSupport.CONSUMER, httpMethod, path, - System.currentTimeMillis() - startTime, ex); - switch (ex) { - case ServiceException serviceException -> throw serviceException; - case RuntimeException runtimeException -> throw runtimeException; - case Error error -> throw error; - default -> { - } - } - throw new IllegalStateException(ex); - } - } - - private String resolvePath(HttpRequestValues requestValues) { - URI uri = requestValues.getUri(); - if (uri != null) { - // 能拿到最终 URI 时优先打印最终请求地址,便于线上排查。 - return uri.toString(); - } - String uriTemplate = requestValues.getUriTemplate(); - if (!StringUtils.hasText(uriTemplate)) { - return null; - } - Map uriVariables = requestValues.getUriVariables(); - String path = uriTemplate; - if (uriVariables != null) { - for (Map.Entry entry : uriVariables.entrySet()) { - path = path.replace("{" + entry.getKey() + "}", String.valueOf(entry.getValue())); - } - } - return path; - } - - @FunctionalInterface - private interface ThrowingSupplier { - - T get() throws Throwable; - } -} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpFeignLogger.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpFeignLogger.java new file mode 100644 index 000000000..08d9a0515 --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpFeignLogger.java @@ -0,0 +1,52 @@ +package org.dromara.common.http.log.support; + +import feign.Logger; +import feign.Request; +import feign.Response; +import feign.Util; +import org.springframework.http.HttpMethod; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * Feign 原生日志桥接。 + */ +public class RemoteHttpFeignLogger extends Logger { + + private final RemoteHttpLogSupport logSupport; + + public RemoteHttpFeignLogger(RemoteHttpLogSupport logSupport) { + this.logSupport = logSupport; + } + + @Override + protected void log(String configKey, String format, Object... args) { + } + + @Override + protected void logRequest(String configKey, Level logLevel, Request request) { + Object[] arguments = request.body() == null ? new Object[0] : new Object[] {request.body()}; + this.logSupport.logRequest(RemoteHttpLogSupport.CONSUMER, HttpMethod.valueOf(request.httpMethod().name()), request.url(), arguments); + } + + @Override + protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) + throws IOException { + byte[] bodyData = response.body() == null ? null : Util.toByteArray(response.body().asInputStream()); + Object responseBody = bodyData == null ? null : new String(bodyData, StandardCharsets.UTF_8); + HttpMethod httpMethod = response.request() == null ? null : HttpMethod.valueOf(response.request().httpMethod().name()); + String path = response.request() == null ? null : response.request().url(); + this.logSupport.logResponse(RemoteHttpLogSupport.CONSUMER, httpMethod, path, elapsedTime, responseBody); + if (bodyData == null) { + return response; + } + return response.toBuilder().body(bodyData).build(); + } + + @Override + protected IOException logIOException(String configKey, Level logLevel, IOException ioe, long elapsedTime) { + this.logSupport.logException(RemoteHttpLogSupport.CONSUMER, null, configKey, elapsedTime, ioe); + return ioe; + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpLogSupport.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpLogSupport.java index e9cdd7a4f..7e690b47a 100644 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpLogSupport.java +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/log/support/RemoteHttpLogSupport.java @@ -1,19 +1,9 @@ package org.dromara.common.http.log.support; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.dromara.common.http.log.enums.RequestLogEnum; -import org.dromara.common.http.properties.RemoteHttpProperties; -import org.dromara.common.json.utils.JsonUtils; import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - /** * 内部 HTTP 日志支持. * @@ -24,50 +14,22 @@ import java.util.Map; * @author Lion Li */ @Slf4j -@RequiredArgsConstructor public class RemoteHttpLogSupport { public static final String CONSUMER = "CONSUMER"; public static final String PROVIDER = "PROVIDER"; - private final RemoteHttpProperties properties; - - public boolean isEnabled() { - return Boolean.TRUE.equals(properties.getRequestLog()); - } - - public boolean isFullLogEnabled() { - return properties.getLogLevel() == RequestLogEnum.FULL; - } - public void logRequest(String client, HttpMethod httpMethod, String path, Object[] arguments) { - if (!isEnabled()) { - return; - } String baseLog = buildBaseLog(client, httpMethod, path); - if (properties.getLogLevel() == RequestLogEnum.INFO) { - log.info("HTTP - 服务调用: {}", baseLog); - return; - } - log.info("HTTP - 服务调用: {},Parameter={}", baseLog, formatArguments(arguments)); + log.info("HTTP - 服务调用: {}", baseLog); } public void logResponse(String client, HttpMethod httpMethod, String path, long elapsed, Object response) { - if (!isEnabled()) { - return; - } String baseLog = buildBaseLog(client, httpMethod, path); - if (properties.getLogLevel() == RequestLogEnum.FULL) { - log.info("HTTP - 服务响应: {},SpendTime=[{}ms],Response={}", baseLog, elapsed, formatValue(unwrapResponse(response))); - return; - } log.info("HTTP - 服务响应: {},SpendTime=[{}ms]", baseLog, elapsed); } public void logException(String client, HttpMethod httpMethod, String path, long elapsed, Throwable throwable) { - if (!isEnabled()) { - return; - } String baseLog = buildBaseLog(client, httpMethod, path); log.error("HTTP - 服务异常: {},SpendTime=[{}ms],Exception={}", baseLog, elapsed, throwable.getMessage(), throwable); } @@ -82,51 +44,4 @@ public class RemoteHttpLogSupport { ']'; } - private String formatArguments(Object[] arguments) { - return formatValue(arguments == null ? new Object[0] : arguments); - } - - private Object unwrapResponse(Object response) { - if (response instanceof ResponseEntity responseEntity) { - return responseEntity.getBody(); - } - return response; - } - - private String formatValue(Object value) { - try { - return JsonUtils.toJsonString(sanitizeValue(value)); - } catch (RuntimeException ignored) { - return String.valueOf(value); - } - } - - private Object sanitizeValue(Object value) { - if (value == null) { - return null; - } - if (value instanceof byte[] bytes) { - // 文件上传这类场景只记录长度,避免二进制内容直接进日志。 - return "byte[" + bytes.length + "]"; - } - if (value instanceof Object[] array) { - Object[] sanitized = new Object[array.length]; - for (int i = 0; i < array.length; i++) { - sanitized[i] = sanitizeValue(array[i]); - } - return sanitized; - } - if (value instanceof Collection collection) { - return collection.stream().map(this::sanitizeValue).toList(); - } - if (value instanceof Map map) { - Map sanitized = new LinkedHashMap<>(map.size()); - map.forEach((key, item) -> sanitized.put(key, sanitizeValue(item))); - return sanitized; - } - if (ObjectUtils.isArray(value)) { - return ObjectUtils.nullSafeToString(value); - } - return value; - } } diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/properties/RemoteHttpProperties.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/properties/RemoteHttpProperties.java deleted file mode 100644 index d40be4719..000000000 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/properties/RemoteHttpProperties.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.dromara.common.http.properties; - -import lombok.Data; -import org.dromara.common.http.log.enums.RequestLogEnum; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * 内部 HTTP 调用配置. - * - * @author Lion Li - */ -@Data -@ConfigurationProperties(prefix = "remote.http") -public class RemoteHttpProperties { - - /** - * 是否开启请求日志. - */ - private Boolean requestLog = Boolean.FALSE; - - /** - * 日志级别. - */ - private RequestLogEnum logLevel = RequestLogEnum.INFO; - -} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/registrar/RemoteHttpServiceRegistrar.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/registrar/RemoteHttpServiceRegistrar.java deleted file mode 100644 index ff4c077c7..000000000 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/registrar/RemoteHttpServiceRegistrar.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.dromara.common.http.registrar; - -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.core.annotation.RemoteHttpService; -import org.dromara.common.http.annotation.RemoteServiceController; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.core.env.Environment; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.ClassUtils; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.web.service.annotation.HttpExchange; -import org.springframework.web.service.registry.AbstractHttpServiceRegistrar; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * 按接口声明自动注册远程 HTTP Service. - * - * 这个注册器负责把“接口声明”转成 Spring HTTP Service Client 代理, - * 同时保留一个和 Dubbo 类似的优化: - * 当前服务自己就提供了该接口实现时,不再注册远程代理,直接走本地 Bean。 - * - * @author Lion Li - */ -public class RemoteHttpServiceRegistrar extends AbstractHttpServiceRegistrar - implements EnvironmentAware, ResourceLoaderAware, BeanClassLoaderAware { - - private Environment environment; - private ResourceLoader resourceLoader; - private ClassLoader beanClassLoader; - private static final String SCAN_PACKAGES_PROPERTY = "remote.http.scan-packages"; - private static final AntPathMatcher PACKAGE_MATCHER = new AntPathMatcher("."); - - @Override - public void setEnvironment(Environment environment) { - super.setEnvironment(environment); - this.environment = environment; - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - super.setResourceLoader(resourceLoader); - this.resourceLoader = resourceLoader; - } - - @Override - public void setBeanClassLoader(ClassLoader beanClassLoader) { - super.setBeanClassLoader(beanClassLoader); - this.beanClassLoader = beanClassLoader; - } - - @Override - protected void registerHttpServices(GroupRegistry registry, AnnotationMetadata importingClassMetadata) { - Set scanPackagePatterns = new LinkedHashSet<>(resolveConfiguredScanPackages()); - if (scanPackagePatterns.isEmpty()) { - return; - } - Set scanBasePackages = resolveScanBasePackages(scanPackagePatterns); - if (scanBasePackages.isEmpty()) { - return; - } - // 先找出当前服务自己已经提供的远程接口,后面这些接口不再注册 HTTP client。 - Set localServiceTypes = resolveLocalServiceTypes(scanBasePackages, scanPackagePatterns); - MultiValueMap groupedServices = resolveRemoteHttpServices(scanBasePackages, scanPackagePatterns, localServiceTypes); - groupedServices.forEach((serviceId, classNames) -> - registry.forGroup(serviceId).registerTypeNames(classNames.toArray(String[]::new))); - } - - private MultiValueMap resolveRemoteHttpServices(Set basePackages, Set scanPackagePatterns, - Set localServiceTypes) { - MultiValueMap groupedServices = new LinkedMultiValueMap<>(); - for (AnnotatedBeanDefinition beanDefinition : scanCandidateComponents(basePackages, RemoteHttpService.class)) { - AnnotationMetadata metadata = beanDefinition.getMetadata(); - if (!metadata.isInterface() || !hasHttpExchange(metadata)) { - continue; - } - String serviceTypeName = metadata.getClassName(); - if (!matchesConfiguredPackage(serviceTypeName, scanPackagePatterns)) { - continue; - } - // 同服务场景直接依赖本地 provider,不再生成 HTTP 代理。 - if (localServiceTypes.contains(serviceTypeName)) { - continue; - } - groupedServices.add(resolveServiceId(metadata), serviceTypeName); - } - return groupedServices; - } - - private Set resolveLocalServiceTypes(Set basePackages, Set scanPackagePatterns) { - MultiValueMap localServiceTypes = new LinkedMultiValueMap<>(); - for (AnnotatedBeanDefinition beanDefinition : scanCandidateComponents(basePackages, RemoteServiceController.class)) { - String className = beanDefinition.getMetadata().getClassName(); - Class beanClass = ClassUtils.resolveClassName(className, this.beanClassLoader); - for (Class interfaceType : ClassUtils.getAllInterfacesForClass(beanClass, this.beanClassLoader)) { - if (interfaceType.isAnnotationPresent(RemoteHttpService.class) - && matchesConfiguredPackage(interfaceType.getName(), scanPackagePatterns)) { - localServiceTypes.add(interfaceType.getName(), className); - } - } - } - // 同一个远程接口只允许一个本地 provider,否则本地短路目标不明确。 - localServiceTypes.forEach((serviceTypeName, providerClassNames) -> { - if (providerClassNames.size() > 1) { - throw new IllegalStateException("Multiple local RemoteServiceController beans found for " - + serviceTypeName + ": " + providerClassNames); - } - }); - return new LinkedHashSet<>(localServiceTypes.keySet()); - } - - private List scanCandidateComponents(Set basePackages, - Class annotationType) { - ClassPathScanningCandidateComponentProvider scanner = createScanner(annotationType); - List beanDefinitions = new ArrayList<>(); - for (String basePackage : basePackages) { - for (BeanDefinition beanDefinition : scanner.findCandidateComponents(basePackage)) { - if (beanDefinition instanceof AnnotatedBeanDefinition annotatedBeanDefinition) { - beanDefinitions.add(annotatedBeanDefinition); - } - } - } - return beanDefinitions; - } - - private ClassPathScanningCandidateComponentProvider createScanner(Class annotationType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) { - @Override - protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { - return beanDefinition.getMetadata().isIndependent(); - } - }; - scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); - if (this.environment != null) { - scanner.setEnvironment(this.environment); - } - if (this.resourceLoader != null) { - scanner.setResourceLoader(this.resourceLoader); - } - return scanner; - } - - private String resolveServiceId(AnnotationMetadata metadata) { - Map attributes = metadata.getAnnotationAttributes(RemoteHttpService.class.getName()); - String serviceId = attributes != null ? String.valueOf(attributes.get("serviceId")) : StringUtils.EMPTY; - if (StringUtils.isBlank(serviceId)) { - throw new IllegalStateException("RemoteHttpService serviceId must not be blank: " + metadata.getClassName()); - } - return serviceId; - } - - private boolean hasHttpExchange(AnnotationMetadata metadata) { - return metadata.isAnnotated(HttpExchange.class.getName()) || metadata.hasAnnotatedMethods(HttpExchange.class.getName()); - } - - private List resolveConfiguredScanPackages() { - if (this.environment == null) { - return Collections.emptyList(); - } - return Binder.get(this.environment).bind(SCAN_PACKAGES_PROPERTY, org.springframework.boot.context.properties.bind.Bindable.listOf(String.class)) - .orElseGet(Collections::emptyList) - .stream() - .filter(StringUtils::isNotBlank) - .distinct() - .toList(); - } - - private Set resolveScanBasePackages(Set scanPackagePatterns) { - Set basePackages = new LinkedHashSet<>(); - for (String packagePattern : scanPackagePatterns) { - String basePackage = resolveScanBasePackage(packagePattern); - if (StringUtils.isNotBlank(basePackage)) { - basePackages.add(basePackage); - } - } - return basePackages; - } - - private String resolveScanBasePackage(String packagePattern) { - int wildcardIndex = packagePattern.indexOf('*'); - if (wildcardIndex < 0) { - return packagePattern; - } - String packagePrefix = packagePattern.substring(0, wildcardIndex); - packagePrefix = StringUtils.substringBeforeLast(packagePrefix, "."); - return StringUtils.defaultString(packagePrefix); - } - - private boolean matchesConfiguredPackage(String className, Set scanPackagePatterns) { - if (scanPackagePatterns.isEmpty()) { - return true; - } - String packageName = ClassUtils.getPackageName(className); - for (String packagePattern : scanPackagePatterns) { - if (PACKAGE_MATCHER.match(packagePattern, packageName)) { - return true; - } - } - return false; - } -} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionCodec.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionCodec.java new file mode 100644 index 000000000..a368bf7f2 --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionCodec.java @@ -0,0 +1,65 @@ +package org.dromara.common.http.support; + +import org.apache.fory.Fory; +import org.apache.fory.ThreadSafeFory; +import org.apache.fory.config.Language; +import org.dromara.common.core.exception.ServiceException; + +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 数据权限上下文编解码器. + * + * 通过 Fory + Base64 把上下文压缩成单个 HTTP Header,避免手工维护复杂类型转换。 + */ +public class RemoteHttpDataPermissionCodec { + + public static final String HEADER_NAME = "X-Remote-Data-Permission"; + + private static final int MAX_HEADER_LENGTH = 6 * 1024; + + private static final ThreadSafeFory FORY = Fory.builder() + .withLanguage(Language.JAVA) + .withRefTracking(true) + .withStringCompressed(true) + .withNumberCompressed(true) + .requireClassRegistration(false) + .buildThreadSafeFory(); + + public String encode(Map context) { + if (context == null || context.isEmpty()) { + return null; + } + try { + byte[] bytes = FORY.serialize(context); + String headerValue = Base64.getEncoder().encodeToString(bytes); + if (headerValue.length() > MAX_HEADER_LENGTH) { + throw new ServiceException("数据权限上下文过大,无法透传"); + } + return headerValue; + } catch (ServiceException e) { + throw e; + } catch (Exception e) { + throw new ServiceException("数据权限上下文序列化失败"); + } + } + + @SuppressWarnings("unchecked") + public Map decode(String headerValue) { + if (headerValue == null || headerValue.isBlank()) { + return Map.of(); + } + try { + byte[] bytes = Base64.getDecoder().decode(headerValue); + Object value = FORY.deserialize(bytes); + if (value instanceof Map map) { + return new LinkedHashMap<>((Map) map); + } + } catch (Exception e) { + throw new ServiceException("数据权限上下文反序列化失败"); + } + throw new ServiceException("数据权限上下文格式非法"); + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionInterceptor.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionInterceptor.java new file mode 100644 index 000000000..10857424f --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionInterceptor.java @@ -0,0 +1,53 @@ +package org.dromara.common.http.support; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.dromara.common.core.utils.StringUtils; +import org.springframework.web.servlet.AsyncHandlerInterceptor; + +import java.util.Map; + +/** + * provider 侧恢复数据权限上下文,并在请求结束后清理,避免线程复用污染。 + */ +public class RemoteHttpDataPermissionInterceptor implements AsyncHandlerInterceptor { + + private static final String CONTEXT_ATTRIBUTE = RemoteHttpDataPermissionInterceptor.class.getName() + ".context"; + + private final RemoteHttpDataPermissionCodec codec; + + public RemoteHttpDataPermissionInterceptor(RemoteHttpDataPermissionCodec codec) { + this.codec = codec; + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + String headerValue = request.getHeader(RemoteHttpDataPermissionCodec.HEADER_NAME); + if (StringUtils.isBlank(headerValue)) { + return true; + } + request.setAttribute(CONTEXT_ATTRIBUTE, RemoteHttpDataPermissionSupport.snapshotContext()); + RemoteHttpDataPermissionSupport.replaceContext(this.codec.decode(headerValue)); + return true; + } + + @Override + public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) { + restoreContext(request); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + restoreContext(request); + } + + @SuppressWarnings("unchecked") + private void restoreContext(HttpServletRequest request) { + Object context = request.getAttribute(CONTEXT_ATTRIBUTE); + if (!(context instanceof Map previousContext)) { + return; + } + RemoteHttpDataPermissionSupport.replaceContext((Map) previousContext); + request.removeAttribute(CONTEXT_ATTRIBUTE); + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionRequestInterceptor.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionRequestInterceptor.java new file mode 100644 index 000000000..637835845 --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionRequestInterceptor.java @@ -0,0 +1,27 @@ +package org.dromara.common.http.support; + +import feign.RequestInterceptor; +import feign.RequestTemplate; + +/** + * consumer 侧数据权限透传拦截器。 + */ +public class RemoteHttpDataPermissionRequestInterceptor implements RequestInterceptor { + + private final RemoteHttpDataPermissionCodec codec; + + public RemoteHttpDataPermissionRequestInterceptor(RemoteHttpDataPermissionCodec codec) { + this.codec = codec; + } + + @Override + public void apply(RequestTemplate requestTemplate) { + if (!RemoteHttpDataPermissionSupport.hasContext()) { + return; + } + String headerValue = this.codec.encode(RemoteHttpDataPermissionSupport.snapshotContext()); + if (headerValue != null) { + requestTemplate.header(RemoteHttpDataPermissionCodec.HEADER_NAME, headerValue); + } + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionSupport.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionSupport.java new file mode 100644 index 000000000..344bfa623 --- /dev/null +++ b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpDataPermissionSupport.java @@ -0,0 +1,31 @@ +package org.dromara.common.http.support; + +import org.dromara.common.mybatis.helper.DataPermissionHelper; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 数据权限上下文访问工具。 + */ +public final class RemoteHttpDataPermissionSupport { + + private RemoteHttpDataPermissionSupport() { + } + + public static boolean hasContext() { + return !DataPermissionHelper.getContext().isEmpty(); + } + + public static Map snapshotContext() { + return new LinkedHashMap<>(DataPermissionHelper.getContext()); + } + + public static void replaceContext(Map context) { + Map currentContext = DataPermissionHelper.getContext(); + currentContext.clear(); + if (context != null && !context.isEmpty()) { + currentContext.putAll(context); + } + } +} diff --git a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpFallbackProxyPostProcessor.java b/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpFallbackProxyPostProcessor.java deleted file mode 100644 index 50e4166a3..000000000 --- a/ruoyi-common/ruoyi-common-http/src/main/java/org/dromara/common/http/support/RemoteHttpFallbackProxyPostProcessor.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.dromara.common.http.support; - -import org.aopalliance.intercept.MethodInterceptor; -import org.dromara.common.core.annotation.RemoteHttpService; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; - -/** - * 远程 HTTP 代理 fallback 包装器. - * - *

仅包装注册器生成的远程 HTTP 代理 Bean。代理调用报错时, - * 按接口上声明的 fallback 实现兜底,不处理本地 provider Bean。 - * - *

这里故意保持和之前 mock/stub 类似的简单约束: - * fallback 必须实现接口本身,且方法签名与接口保持一致。

- * - * @author Lion Li - */ -public class RemoteHttpFallbackProxyPostProcessor - implements BeanPostProcessor, BeanFactoryAware, BeanClassLoaderAware { - - private static final String HTTP_SERVICE_GROUP_NAME_ATTRIBUTE = "httpServiceGroupName"; - private static final String FALLBACK_WRAPPED_ATTRIBUTE = "remoteHttpFallbackWrapped"; - - private ConfigurableListableBeanFactory beanFactory; - private ClassLoader beanClassLoader; - - @Override - public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory) throws BeansException { - this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - if (bean instanceof FallbackDecoratedProxy) { - return bean; - } - Class serviceInterface = resolveRemoteServiceInterface(beanName, bean); - if (serviceInterface == null) { - return bean; - } - RemoteHttpService remoteHttpService = serviceInterface.getAnnotation(RemoteHttpService.class); - if (remoteHttpService == null || remoteHttpService.fallback() == void.class) { - return bean; - } - Class fallbackClass = remoteHttpService.fallback(); - if (!serviceInterface.isAssignableFrom(fallbackClass)) { - throw new IllegalStateException("Fallback class must implement remote service interface: " - + fallbackClass.getName() + " -> " + serviceInterface.getName()); - } - ProxyFactory proxyFactory = new ProxyFactory(bean); - proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(bean.getClass(), this.beanClassLoader)); - proxyFactory.addInterface(FallbackDecoratedProxy.class); - proxyFactory.addAdvice((MethodInterceptor) invocation -> { - Method method = invocation.getMethod(); - if (method.getDeclaringClass() == Object.class) { - return invocation.proceed(); - } - try { - return invocation.proceed(); - } catch (Throwable ex) { - return invokeFallback(serviceInterface, fallbackClass, method, invocation.getArguments(), ex); - } - }); - markWrapped(beanName); - return proxyFactory.getProxy(this.beanClassLoader); - } - - private Class resolveRemoteServiceInterface(String beanName, Object bean) { - if (this.beanFactory == null || !this.beanFactory.containsBeanDefinition(beanName)) { - return null; - } - BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition(beanName); - if (beanDefinition.getAttribute(HTTP_SERVICE_GROUP_NAME_ATTRIBUTE) == null) { - return null; - } - if (Boolean.TRUE.equals(beanDefinition.getAttribute(FALLBACK_WRAPPED_ATTRIBUTE))) { - return null; - } - Class beanClass = resolveBeanClass(beanDefinition); - if (beanClass != null && beanClass.isInterface() && beanClass.isAnnotationPresent(RemoteHttpService.class)) { - return beanClass; - } - for (Class interfaceType : ClassUtils.getAllInterfacesForClass(bean.getClass(), this.beanClassLoader)) { - if (interfaceType.isAnnotationPresent(RemoteHttpService.class)) { - return interfaceType; - } - } - return null; - } - - private Class resolveBeanClass(BeanDefinition beanDefinition) { - String beanClassName = beanDefinition.getBeanClassName(); - return beanClassName == null ? null : ClassUtils.resolveClassName(beanClassName, this.beanClassLoader); - } - - private Object invokeFallback(Class serviceInterface, Class fallbackClass, Method method, Object[] args, Throwable ex) - throws Throwable { - Object fallbackInstance = instantiateFallback(fallbackClass); - Method fallbackMethod = ReflectionUtils.findMethod(fallbackClass, method.getName(), method.getParameterTypes()); - if (fallbackMethod == null) { - throw unwrap(ex); - } - ReflectionUtils.makeAccessible(fallbackMethod); - return invokeMethod(fallbackInstance, fallbackMethod, args); - } - - private Object instantiateFallback(Class fallbackClass) { - if (this.beanFactory == null) { - throw new IllegalStateException("BeanFactory not initialized for remote fallback: " + fallbackClass.getName()); - } - return this.beanFactory.getBean(fallbackClass); - } - - private void markWrapped(String beanName) { - if (this.beanFactory == null || !this.beanFactory.containsBeanDefinition(beanName)) { - return; - } - this.beanFactory.getBeanDefinition(beanName).setAttribute(FALLBACK_WRAPPED_ATTRIBUTE, true); - } - - private Object invokeMethod(Object target, Method method, Object[] args) throws Throwable { - try { - return method.invoke(target, args); - } catch (InvocationTargetException ex) { - throw unwrap(ex.getTargetException()); - } catch (IllegalAccessException ex) { - throw new IllegalStateException("Could not invoke remote fallback method: " + method, ex); - } catch (UndeclaredThrowableException ex) { - throw unwrap(ex); - } catch (RuntimeException ex) { - throw unwrap(ex); - } - } - - private Throwable unwrap(Throwable throwable) { - Throwable current = throwable; - while (current instanceof InvocationTargetException invocationTargetException && invocationTargetException.getTargetException() != null) { - current = invocationTargetException.getTargetException(); - } - while (current instanceof UndeclaredThrowableException undeclaredThrowableException && undeclaredThrowableException.getUndeclaredThrowable() != null) { - current = undeclaredThrowableException.getUndeclaredThrowable(); - } - return current; - } - - private interface FallbackDecoratedProxy { - } -} diff --git a/ruoyi-common/ruoyi-common-http/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-http/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 9b53874f5..e7cd7b28b 100644 --- a/ruoyi-common/ruoyi-common-http/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-http/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,2 @@ org.dromara.common.http.config.RemoteHttpAutoConfiguration +org.dromara.common.http.config.RemoteHttpDataPermissionAutoConfiguration diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml index f8a5a477f..5f31a1fe9 100644 --- a/ruoyi-common/ruoyi-common-redis/pom.xml +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -68,7 +68,6 @@ org.apache.fory fory-core - 0.13.1 diff --git a/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/handler/GatewayExceptionHandler.java b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/handler/GatewayExceptionHandler.java index 18d6b6256..d5f69514a 100644 --- a/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/handler/GatewayExceptionHandler.java +++ b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/handler/GatewayExceptionHandler.java @@ -34,7 +34,8 @@ public class GatewayExceptionHandler { public void handle(HttpServletRequest request, HttpServletResponse response, Throwable ex) throws IOException { int code; String msg; - if ("NotFoundException".equals(ex.getClass().getSimpleName())) { + if ("NotFoundException".equals(ex.getClass().getSimpleName()) + || ex.getMessage().contains("Unable to find instance")) { code = HttpStatus.NOT_FOUND; msg = "服务未找到"; } else if (ex instanceof ResponseStatusException responseStatusException) { diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java index fc7d6ab7f..88871775e 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java @@ -28,7 +28,7 @@ import java.util.List; */ @Slf4j @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/file") public class RemoteFileServiceImpl implements RemoteFileService { private final ISysOssService sysOssService; diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMailServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMailServiceImpl.java index 59baae50a..f5564d9e8 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMailServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMailServiceImpl.java @@ -14,7 +14,7 @@ import org.dromara.resource.api.RemoteMailService; */ @Slf4j @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/mail") public class RemoteMailServiceImpl implements RemoteMailService { /** diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMessageServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMessageServiceImpl.java index 528b8511e..4d84cc1a7 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMessageServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteMessageServiceImpl.java @@ -16,7 +16,7 @@ import java.util.List; */ @Slf4j @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/message") public class RemoteMessageServiceImpl implements RemoteMessageService { /** diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteSmsServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteSmsServiceImpl.java index b2764ae5e..d2cb9f2d0 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteSmsServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/dubbo/RemoteSmsServiceImpl.java @@ -21,7 +21,7 @@ import java.util.List; */ @Slf4j @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/inner/remote/resource/sms") public class RemoteSmsServiceImpl implements RemoteSmsService { /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteClientServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteClientServiceImpl.java index bc3eb263c..a5403dc21 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteClientServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteClientServiceImpl.java @@ -14,7 +14,7 @@ import org.dromara.system.service.ISysClientService; * @author Michelle.Chung */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/client") public class RemoteClientServiceImpl implements RemoteClientService { private final ISysClientService sysClientService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java index 9d9b946e2..6afb1332c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteConfigServiceImpl.java @@ -15,7 +15,7 @@ import java.util.List; * @author Michelle.Chung */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/config") public class RemoteConfigServiceImpl implements RemoteConfigService { private final ISysConfigService configService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDataScopeServiceImpl.java index ae0cd18f5..9ff55785f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDataScopeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDataScopeServiceImpl.java @@ -25,7 +25,7 @@ import java.util.List; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/data-scope") public class RemoteDataScopeServiceImpl implements RemoteDataScopeService { private final SysRoleDeptMapper roleDeptMapper; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java index 19cf7dd23..dbc08873e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java @@ -25,7 +25,7 @@ import java.util.Map; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/dept") public class RemoteDeptServiceImpl implements RemoteDeptService { private final ISysDeptService deptService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDictServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDictServiceImpl.java index e910f5158..db36b0c43 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDictServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDictServiceImpl.java @@ -18,7 +18,7 @@ import java.util.List; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/dict") public class RemoteDictServiceImpl implements RemoteDictService { private final ISysDictTypeService sysDictTypeService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteLogServiceImpl.java index 527da225a..0fa37d304 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteLogServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteLogServiceImpl.java @@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/log") public class RemoteLogServiceImpl implements RemoteLogService { private final ISysOperLogService operLogService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePermissionServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePermissionServiceImpl.java index 8149f4fb6..154674bd7 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePermissionServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePermissionServiceImpl.java @@ -13,7 +13,7 @@ import java.util.Set; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/permission") public class RemotePermissionServiceImpl implements RemotePermissionService { private final ISysPermissionService permissionService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java index ad2eaa098..0fc1d66d8 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemotePostServiceImpl.java @@ -20,7 +20,7 @@ import java.util.Map; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/post") public class RemotePostServiceImpl implements RemotePostService { private final SysPostMapper postMapper; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteRoleServiceImpl.java index 6289118b7..e7017b434 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteRoleServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteRoleServiceImpl.java @@ -20,7 +20,7 @@ import java.util.Map; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/role") public class RemoteRoleServiceImpl implements RemoteRoleService { private final SysRoleMapper roleMapper; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java index 1344641be..55851b0b3 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java @@ -18,7 +18,7 @@ import java.util.List; * @author Michelle.Chung */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/social") public class RemoteSocialServiceImpl implements RemoteSocialService { private final ISysSocialService sysSocialService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteTaskAssigneeServiceImpl.java index 1630343b4..e56a17aae 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteTaskAssigneeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteTaskAssigneeServiceImpl.java @@ -31,7 +31,7 @@ import java.util.Map; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/task-assignee") public class RemoteTaskAssigneeServiceImpl implements RemoteTaskAssigneeService { // 上级Service注入下级Service 其他Service永远不可能注入当前类 避免循环注入 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java index 6d2c428a6..566c78711 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java @@ -45,7 +45,7 @@ import java.util.*; * @author Lion Li */ @RequiredArgsConstructor -@RemoteServiceController +@RemoteServiceController(path = "/remote/user") public class RemoteUserServiceImpl implements RemoteUserService { private final ISysUserService userService; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/dubbo/RemoteWorkflowServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/dubbo/RemoteWorkflowServiceImpl.java index 06753c852..8f8dc2526 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/dubbo/RemoteWorkflowServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/dubbo/RemoteWorkflowServiceImpl.java @@ -17,7 +17,7 @@ import java.util.Map; * @Author ZETA * @Date 2024/6/3 */ -@RemoteServiceController +@RemoteServiceController(path = "/remote/workflow") @RequiredArgsConstructor public class RemoteWorkflowServiceImpl implements RemoteWorkflowService { diff --git a/script/config/nacos/application-common.yml b/script/config/nacos/application-common.yml index c212a58fa..b13691ffc 100644 --- a/script/config/nacos/application-common.yml +++ b/script/config/nacos/application-common.yml @@ -9,20 +9,10 @@ server: # 最大线程数 max: 256 -remote: - http: - # 远程接口扫描范围,支持 Ant 风格包路径 - scan-packages: - - org.dromara.**.api - # 全局请求log - request-log: true - # info 基础信息 param 参数信息 full 全部 - log-level: info - spring: http: clients: - # 默认 client HTTP 请求超时,供 RestClient / HTTP Service Client 复用 + # Spring HTTP 客户端默认超时配置,供非 Feign 客户端复用 connect-timeout: 3s read-timeout: 10s imperative: @@ -66,6 +56,9 @@ spring: # 允许对象忽略json中不存在的属性 fail_on_unknown_properties: false cloud: + openfeign: + circuitbreaker: + enabled: true inetutils: # 指定全局使用ip网段 preferred-networks: