mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2026-05-07 20:41:26 +08:00
Revert "[重大更新] 使用 spring feign 替代 HttpServiceClient (功能太新 支持不完全 使用成本太高)"
This reverts commit 485c2001
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -60,7 +60,6 @@
|
||||
<mica-mqtt.version>2.5.11</mica-mqtt.version>
|
||||
<!-- mq配置 -->
|
||||
<rocketmq.version>2.3.4</rocketmq.version>
|
||||
<fory.version>0.16.0</fory.version>
|
||||
|
||||
<!-- 插件版本 -->
|
||||
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
||||
@@ -366,12 +365,6 @@
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.fory</groupId>
|
||||
<artifactId>fory-core</artifactId>
|
||||
<version>${fory.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Warm-Flow国产工作流引擎, 在线文档:http://warm-flow.cn/ -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
|
||||
@@ -22,11 +22,4 @@
|
||||
ruoyi-api系统接口
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
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;
|
||||
|
||||
@@ -18,8 +16,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteFileService", name = "ruoyi-resource", path = "/remote/file",
|
||||
fallbackFactory = RemoteFileServiceFallbackFactory.class, primary = false)
|
||||
@RemoteHttpService(value = "ruoyi-resource", fallback = RemoteFileServiceFallback.class)
|
||||
@HttpExchange("/remote/file")
|
||||
public interface RemoteFileService {
|
||||
|
||||
/**
|
||||
@@ -28,7 +26,7 @@ public interface RemoteFileService {
|
||||
* @param file 文件信息
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
@PostExchange("/upload")
|
||||
RemoteFile upload(@RequestParam String name, @RequestParam String originalFilename,
|
||||
@RequestParam String contentType, @RequestBody byte[] file) throws ServiceException;
|
||||
|
||||
@@ -38,7 +36,7 @@ public interface RemoteFileService {
|
||||
* @param ossIds ossId串逗号分隔
|
||||
* @return url串逗号分隔
|
||||
*/
|
||||
@GetMapping("/select-url-by-ids")
|
||||
@GetExchange("/select-url-by-ids")
|
||||
String selectUrlByIds(@RequestParam String ossIds);
|
||||
|
||||
/**
|
||||
@@ -47,7 +45,6 @@ public interface RemoteFileService {
|
||||
* @param ossIds ossId串逗号分隔
|
||||
* @return 列表
|
||||
*/
|
||||
@GetMapping("/select-by-ids")
|
||||
@GetExchange("/select-by-ids")
|
||||
List<RemoteFile> selectByIds(@RequestParam String ossIds);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
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<RemoteFile> selectByIds(String ossIds) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
return List.of();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +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 org.springframework.cloud.openfeign.FallbackFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文件服务 fallback factory.
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
public class RemoteFileServiceFallbackFactory implements FallbackFactory<RemoteFileService> {
|
||||
|
||||
@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<RemoteFile> selectByIds(String ossIds) {
|
||||
log.warn("文件服务调用失败, 已触发 fallback", cause);
|
||||
return List.of();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
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
|
||||
*/
|
||||
@FeignClient(contextId = "remoteMailService", name = "ruoyi-resource", path = "/remote/mail", primary = false)
|
||||
@RemoteHttpService("ruoyi-resource")
|
||||
@HttpExchange("/remote/mail")
|
||||
public interface RemoteMailService {
|
||||
|
||||
/**
|
||||
@@ -21,9 +22,7 @@ public interface RemoteMailService {
|
||||
* @param subject 标题
|
||||
* @param text 内容
|
||||
*/
|
||||
@PostMapping("/send")
|
||||
@PostExchange("/send")
|
||||
void send(@RequestParam String to, @RequestParam String subject, @RequestParam String text) throws ServiceException;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
|
||||
@@ -16,8 +13,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteMessageService", name = "ruoyi-resource", path = "/remote/message",
|
||||
fallbackFactory = RemoteMessageServiceFallbackFactory.class, primary = false)
|
||||
@RemoteHttpService(value = "ruoyi-resource", fallback = RemoteMessageServiceFallback.class)
|
||||
@HttpExchange("/remote/message")
|
||||
public interface RemoteMessageService {
|
||||
|
||||
/**
|
||||
@@ -26,7 +23,7 @@ public interface RemoteMessageService {
|
||||
* @param sessionKey session主键 一般为用户id
|
||||
* @param message 消息文本
|
||||
*/
|
||||
@PostMapping("/publish-message")
|
||||
@PostExchange("/publish-message")
|
||||
void publishMessage(@RequestBody List<Long> sessionKey, @RequestParam String message);
|
||||
|
||||
/**
|
||||
@@ -34,7 +31,6 @@ public interface RemoteMessageService {
|
||||
*
|
||||
* @param message 消息内容
|
||||
*/
|
||||
@PostMapping("/publish-all")
|
||||
@PostExchange("/publish-all")
|
||||
void publishAll(@RequestParam String message);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
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<Long> sessionKey, String message) {
|
||||
log.warn("消息服务调用失败, 已触发熔断降级");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布订阅的消息(群发)
|
||||
*
|
||||
* @param message 消息内容
|
||||
*/
|
||||
@Override
|
||||
public void publishAll(String message) {
|
||||
log.warn("消息服务调用失败, 已触发熔断降级");
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
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<RemoteMessageService> {
|
||||
|
||||
@Override
|
||||
public RemoteMessageService create(Throwable cause) {
|
||||
return new RemoteMessageService() {
|
||||
@Override
|
||||
public void publishMessage(List<Long> sessionKey, String message) {
|
||||
log.warn("消息服务调用失败, 已触发 fallback", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishAll(String message) {
|
||||
log.warn("消息服务调用失败, 已触发 fallback", cause);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,13 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
@@ -20,7 +17,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Feng
|
||||
*/
|
||||
@FeignClient(contextId = "remoteSmsService", name = "ruoyi-resource", path = "/inner/remote/resource/sms", primary = false)
|
||||
@RemoteHttpService("ruoyi-resource")
|
||||
@HttpExchange("/inner/remote/resource/sms")
|
||||
public interface RemoteSmsService {
|
||||
|
||||
/**
|
||||
@@ -30,7 +28,7 @@ public interface RemoteSmsService {
|
||||
* @param message 短信内容
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/send-text")
|
||||
@PostExchange("/send-text")
|
||||
RemoteSms sendMessage(@RequestParam String phone, @RequestParam String message);
|
||||
|
||||
/**
|
||||
@@ -40,7 +38,7 @@ public interface RemoteSmsService {
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/send-vars")
|
||||
@PostExchange("/send-vars")
|
||||
RemoteSms sendMessage(@RequestParam String phone, @RequestBody LinkedHashMap<String, String> messages);
|
||||
|
||||
/**
|
||||
@@ -51,7 +49,7 @@ public interface RemoteSmsService {
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/send-template")
|
||||
@PostExchange("/send-template")
|
||||
RemoteSms sendMessage(@RequestParam String phone, @RequestParam String templateId,
|
||||
@RequestBody LinkedHashMap<String, String> messages);
|
||||
|
||||
@@ -62,7 +60,7 @@ public interface RemoteSmsService {
|
||||
* @param message 短信内容
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/message-texting")
|
||||
@PostExchange("/message-texting")
|
||||
RemoteSms messageTexting(@RequestBody List<String> phones, @RequestParam String message);
|
||||
|
||||
/**
|
||||
@@ -73,7 +71,7 @@ public interface RemoteSmsService {
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/message-texting-template")
|
||||
@PostExchange("/message-texting-template")
|
||||
default RemoteSms messageTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||
return messageTextingTemplate(new RemoteSmsBatch(phones, templateId, messages));
|
||||
}
|
||||
@@ -84,7 +82,7 @@ public interface RemoteSmsService {
|
||||
* @param request 群发模板短信请求
|
||||
* @return 封装了短信发送结果的 RemoteSms 对象
|
||||
*/
|
||||
@PostMapping("/message-texting-template")
|
||||
@PostExchange("/message-texting-template")
|
||||
RemoteSms messageTextingTemplate(@RequestBody RemoteSmsBatch request);
|
||||
|
||||
/**
|
||||
@@ -93,7 +91,7 @@ public interface RemoteSmsService {
|
||||
* @param phone 目标手机号
|
||||
* @param message 短信内容
|
||||
*/
|
||||
@PostMapping("/send-async-text")
|
||||
@PostExchange("/send-async-text")
|
||||
void sendMessageAsync(@RequestParam String phone, @RequestParam String message);
|
||||
|
||||
/**
|
||||
@@ -103,7 +101,7 @@ public interface RemoteSmsService {
|
||||
* @param templateId 短信模板ID
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
*/
|
||||
@PostMapping("/send-async-template")
|
||||
@PostExchange("/send-async-template")
|
||||
void sendMessageAsync(@RequestParam String phone, @RequestParam String templateId,
|
||||
@RequestBody LinkedHashMap<String, String> messages);
|
||||
|
||||
@@ -114,7 +112,7 @@ public interface RemoteSmsService {
|
||||
* @param message 短信内容
|
||||
* @param delayedTime 延迟发送时间(毫秒)
|
||||
*/
|
||||
@PostMapping("/delay-text")
|
||||
@PostExchange("/delay-text")
|
||||
void delayMessage(@RequestParam String phone, @RequestParam String message, @RequestParam Long delayedTime);
|
||||
|
||||
/**
|
||||
@@ -125,7 +123,7 @@ public interface RemoteSmsService {
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
* @param delayedTime 延迟发送时间(毫秒)
|
||||
*/
|
||||
@PostMapping("/delay-template")
|
||||
@PostExchange("/delay-template")
|
||||
void delayMessage(@RequestParam String phone, @RequestParam String templateId,
|
||||
@RequestBody LinkedHashMap<String, String> messages, @RequestParam Long delayedTime);
|
||||
|
||||
@@ -136,7 +134,7 @@ public interface RemoteSmsService {
|
||||
* @param message 短信内容
|
||||
* @param delayedTime 延迟发送时间(毫秒)
|
||||
*/
|
||||
@PostMapping("/delay-message-texting")
|
||||
@PostExchange("/delay-message-texting")
|
||||
void delayMessageTexting(@RequestBody List<String> phones, @RequestParam String message, @RequestParam Long delayedTime);
|
||||
|
||||
/**
|
||||
@@ -147,7 +145,7 @@ public interface RemoteSmsService {
|
||||
* @param messages 短信模板参数,使用 LinkedHashMap 以保持参数顺序
|
||||
* @param delayedTime 延迟发送时间(毫秒)
|
||||
*/
|
||||
@PostMapping("/delay-message-texting-template")
|
||||
@PostExchange("/delay-message-texting-template")
|
||||
default void delayMessageTexting(List<String> phones, String templateId,
|
||||
LinkedHashMap<String, String> messages, Long delayedTime) {
|
||||
delayMessageTextingTemplate(new RemoteSmsDelayBatch(phones, templateId, messages, delayedTime));
|
||||
@@ -158,7 +156,7 @@ public interface RemoteSmsService {
|
||||
*
|
||||
* @param request 延迟群发模板短信请求
|
||||
*/
|
||||
@PostMapping("/delay-message-texting-template")
|
||||
@PostExchange("/delay-message-texting-template")
|
||||
void delayMessageTextingTemplate(@RequestBody RemoteSmsDelayBatch request);
|
||||
|
||||
/**
|
||||
@@ -166,7 +164,7 @@ public interface RemoteSmsService {
|
||||
*
|
||||
* @param phone 手机号
|
||||
*/
|
||||
@PostMapping("/add-blacklist-one")
|
||||
@PostExchange("/add-blacklist-one")
|
||||
void addBlacklist(@RequestParam String phone);
|
||||
|
||||
/**
|
||||
@@ -174,7 +172,7 @@ public interface RemoteSmsService {
|
||||
*
|
||||
* @param phones 手机号列表
|
||||
*/
|
||||
@PostMapping("/add-blacklist-list")
|
||||
@PostExchange("/add-blacklist-list")
|
||||
void addBlacklist(@RequestBody List<String> phones);
|
||||
|
||||
/**
|
||||
@@ -182,7 +180,7 @@ public interface RemoteSmsService {
|
||||
*
|
||||
* @param phone 手机号
|
||||
*/
|
||||
@PostMapping("/remove-blacklist-one")
|
||||
@PostExchange("/remove-blacklist-one")
|
||||
void removeBlacklist(@RequestParam String phone);
|
||||
|
||||
/**
|
||||
@@ -190,8 +188,7 @@ public interface RemoteSmsService {
|
||||
*
|
||||
* @param phones 手机号
|
||||
*/
|
||||
@PostMapping("/remove-blacklist-list")
|
||||
@PostExchange("/remove-blacklist-list")
|
||||
void removeBlacklist(@RequestBody List<String> phones);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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
|
||||
*/
|
||||
@FeignClient(contextId = "remoteClientService", name = "ruoyi-system", path = "/remote/client", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/client")
|
||||
public interface RemoteClientService {
|
||||
|
||||
/**
|
||||
@@ -23,8 +21,7 @@ public interface RemoteClientService {
|
||||
* @param clientId 客户端id
|
||||
* @return 客户端对象
|
||||
*/
|
||||
@GetMapping("/query-by-client-id")
|
||||
@GetExchange("/query-by-client-id")
|
||||
RemoteClientVo queryByClientId(@RequestParam String clientId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
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;
|
||||
@@ -19,14 +16,15 @@ import java.util.List;
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@FeignClient(contextId = "remoteConfigService", name = "ruoyi-system", path = "/remote/config", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/config")
|
||||
public interface RemoteConfigService {
|
||||
|
||||
/**
|
||||
* 获取注册开关
|
||||
* @return true开启,false关闭
|
||||
*/
|
||||
@GetMapping("/select-register-enabled")
|
||||
@GetExchange("/select-register-enabled")
|
||||
boolean selectRegisterEnabled();
|
||||
|
||||
/**
|
||||
@@ -35,7 +33,7 @@ public interface RemoteConfigService {
|
||||
* @param configKey 参数 key
|
||||
* @return 参数值
|
||||
*/
|
||||
@GetMapping("/get-config-value")
|
||||
@GetExchange("/get-config-value")
|
||||
String getConfigValue(@RequestParam String configKey);
|
||||
|
||||
/**
|
||||
@@ -123,4 +121,3 @@ public interface RemoteConfigService {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.service.annotation.GetExchange;
|
||||
import org.springframework.web.service.annotation.HttpExchange;
|
||||
|
||||
/**
|
||||
* 数据权限服务
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteDataScopeService", name = "ruoyi-system", path = "/remote/data-scope", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/data-scope")
|
||||
public interface RemoteDataScopeService {
|
||||
|
||||
/**
|
||||
@@ -22,7 +20,7 @@ public interface RemoteDataScopeService {
|
||||
* @param roleId 角色ID
|
||||
* @return 返回角色的自定义权限语句,如果没有找到则返回 null
|
||||
*/
|
||||
@GetMapping("/role-custom")
|
||||
@GetExchange("/role-custom")
|
||||
String getRoleCustom(@RequestParam Long roleId);
|
||||
|
||||
/**
|
||||
@@ -31,8 +29,7 @@ public interface RemoteDataScopeService {
|
||||
* @param deptId 部门ID
|
||||
* @return 返回部门及其下级的权限语句,如果没有找到则返回 null
|
||||
*/
|
||||
@GetMapping("/dept-and-child")
|
||||
@GetExchange("/dept-and-child")
|
||||
String getDeptAndChild(@RequestParam Long deptId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
@@ -19,7 +17,8 @@ import java.util.Map;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteDeptService", name = "ruoyi-system", path = "/remote/dept", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/dept")
|
||||
public interface RemoteDeptService {
|
||||
|
||||
/**
|
||||
@@ -28,7 +27,7 @@ public interface RemoteDeptService {
|
||||
* @param deptIds 部门ID串逗号分隔
|
||||
* @return 部门名称串逗号分隔
|
||||
*/
|
||||
@GetMapping("/select-dept-name-by-ids")
|
||||
@GetExchange("/select-dept-name-by-ids")
|
||||
String selectDeptNameByIds(@RequestParam String deptIds);
|
||||
|
||||
/**
|
||||
@@ -37,7 +36,7 @@ public interface RemoteDeptService {
|
||||
* @param deptId 部门ID,用于指定需要查询的部门
|
||||
* @return 返回该部门的负责人ID
|
||||
*/
|
||||
@GetMapping("/select-dept-leader-by-id")
|
||||
@GetExchange("/select-dept-leader-by-id")
|
||||
Long selectDeptLeaderById(@RequestParam Long deptId);
|
||||
|
||||
/**
|
||||
@@ -45,7 +44,7 @@ public interface RemoteDeptService {
|
||||
*
|
||||
* @return 部门列表
|
||||
*/
|
||||
@GetMapping("/select-depts-by-list")
|
||||
@GetExchange("/select-depts-by-list")
|
||||
List<RemoteDeptVo> selectDeptsByList();
|
||||
|
||||
/**
|
||||
@@ -54,8 +53,7 @@ public interface RemoteDeptService {
|
||||
* @param deptIds 部门 ID 列表
|
||||
* @return Map,其中 key 为部门 ID,value 为对应的部门名称
|
||||
*/
|
||||
@PostMapping("/select-dept-names-by-ids")
|
||||
@PostExchange("/select-dept-names-by-ids")
|
||||
Map<Long, String> selectDeptNamesByIds(@RequestBody Collection<Long> deptIds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
|
||||
@@ -17,7 +14,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteDictService", name = "ruoyi-system", path = "/remote/dict", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/dict")
|
||||
public interface RemoteDictService {
|
||||
|
||||
/**
|
||||
@@ -26,7 +24,7 @@ public interface RemoteDictService {
|
||||
* @param dictType 字典类型
|
||||
* @return 字典类型
|
||||
*/
|
||||
@GetMapping("/select-dict-type-by-type")
|
||||
@GetExchange("/select-dict-type-by-type")
|
||||
RemoteDictTypeVo selectDictTypeByType(@RequestParam String dictType);
|
||||
|
||||
/**
|
||||
@@ -35,8 +33,7 @@ public interface RemoteDictService {
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据集合信息
|
||||
*/
|
||||
@GetMapping("/select-dict-data-by-type")
|
||||
@GetExchange("/select-dict-data-by-type")
|
||||
List<RemoteDictDataVo> selectDictDataByType(@RequestParam String dictType);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +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.annotation.RemoteHttpService;
|
||||
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
|
||||
*/
|
||||
@FeignClient(contextId = "remoteLogService", name = "ruoyi-system", path = "/remote/log", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/log")
|
||||
public interface RemoteLogService {
|
||||
|
||||
/**
|
||||
@@ -23,7 +21,7 @@ public interface RemoteLogService {
|
||||
*
|
||||
* @param sysOperLog 日志实体
|
||||
*/
|
||||
@PostMapping("/save-log")
|
||||
@PostExchange("/save-log")
|
||||
void saveLog(@RequestBody RemoteOperLogBo sysOperLog);
|
||||
|
||||
/**
|
||||
@@ -31,8 +29,7 @@ public interface RemoteLogService {
|
||||
*
|
||||
* @param sysLoginInfo 访问实体
|
||||
*/
|
||||
@PostMapping("/save-login-info")
|
||||
@PostExchange("/save-login-info")
|
||||
void saveLoginInfo(@RequestBody RemoteLoginInfoBo sysLoginInfo);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
|
||||
@@ -15,7 +12,8 @@ import java.util.Set;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remotePermissionService", name = "ruoyi-system", path = "/remote/permission", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/permission")
|
||||
public interface RemotePermissionService {
|
||||
|
||||
/**
|
||||
@@ -24,7 +22,7 @@ public interface RemotePermissionService {
|
||||
* @param userId 用户id
|
||||
* @return 角色权限信息
|
||||
*/
|
||||
@GetMapping("/role-permission")
|
||||
@GetExchange("/role-permission")
|
||||
Set<String> getRolePermission(@RequestParam Long userId);
|
||||
|
||||
/**
|
||||
@@ -33,8 +31,7 @@ public interface RemotePermissionService {
|
||||
* @param userId 用户id
|
||||
* @return 菜单权限信息
|
||||
*/
|
||||
@GetMapping("/menu-permission")
|
||||
@GetExchange("/menu-permission")
|
||||
Set<String> getMenuPermission(@RequestParam Long userId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
@@ -16,7 +13,8 @@ import java.util.Map;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remotePostService", name = "ruoyi-system", path = "/remote/post", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/post")
|
||||
public interface RemotePostService {
|
||||
|
||||
/**
|
||||
@@ -25,8 +23,7 @@ public interface RemotePostService {
|
||||
* @param postIds 岗位 ID 列表
|
||||
* @return Map,其中 key 为岗位 ID,value 为对应的岗位名称
|
||||
*/
|
||||
@PostMapping("/select-post-names-by-ids")
|
||||
@PostExchange("/select-post-names-by-ids")
|
||||
Map<Long, String> selectPostNamesByIds(@RequestBody Collection<Long> postIds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
@@ -16,7 +13,8 @@ import java.util.Map;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteRoleService", name = "ruoyi-system", path = "/remote/role", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/role")
|
||||
public interface RemoteRoleService {
|
||||
|
||||
/**
|
||||
@@ -25,8 +23,7 @@ public interface RemoteRoleService {
|
||||
* @param roleIds 角色 ID 列表
|
||||
* @return Map,其中 key 为角色 ID,value 为对应的角色名称
|
||||
*/
|
||||
@PostMapping("/select-role-names-by-ids")
|
||||
@PostExchange("/select-role-names-by-ids")
|
||||
Map<Long, String> selectRoleNamesByIds(@RequestBody Collection<Long> roleIds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
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.annotation.RemoteHttpService;
|
||||
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;
|
||||
|
||||
@@ -18,7 +16,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@FeignClient(contextId = "remoteSocialService", name = "ruoyi-system", path = "/remote/social", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/social")
|
||||
public interface RemoteSocialService {
|
||||
|
||||
/**
|
||||
@@ -27,7 +26,7 @@ public interface RemoteSocialService {
|
||||
* @param authId 认证id
|
||||
* @return 授权信息
|
||||
*/
|
||||
@GetMapping("/select-by-auth-id")
|
||||
@GetExchange("/select-by-auth-id")
|
||||
List<RemoteSocialVo> selectByAuthId(@RequestParam String authId);
|
||||
|
||||
/**
|
||||
@@ -35,7 +34,7 @@ public interface RemoteSocialService {
|
||||
*
|
||||
* @param bo 社会化关系业务对象
|
||||
*/
|
||||
@PostMapping("/query-list")
|
||||
@PostExchange("/query-list")
|
||||
List<RemoteSocialVo> queryList(@RequestBody RemoteSocialBo bo);
|
||||
|
||||
/**
|
||||
@@ -43,7 +42,7 @@ public interface RemoteSocialService {
|
||||
*
|
||||
* @param bo 社会化关系业务对象
|
||||
*/
|
||||
@PostMapping("/insert-by-bo")
|
||||
@PostExchange("/insert-by-bo")
|
||||
void insertByBo(@RequestBody RemoteSocialBo bo);
|
||||
|
||||
/**
|
||||
@@ -51,7 +50,7 @@ public interface RemoteSocialService {
|
||||
*
|
||||
* @param bo 社会化关系业务对象
|
||||
*/
|
||||
@PostMapping("/update-by-bo")
|
||||
@PostExchange("/update-by-bo")
|
||||
void updateByBo(@RequestBody RemoteSocialBo bo);
|
||||
|
||||
/**
|
||||
@@ -60,8 +59,7 @@ public interface RemoteSocialService {
|
||||
* @param socialId 社会化关系ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/delete-with-valid-by-id")
|
||||
@PostExchange("/delete-with-valid-by-id")
|
||||
Boolean deleteWithValidById(@RequestParam Long socialId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +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.annotation.RemoteHttpService;
|
||||
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
|
||||
*/
|
||||
@FeignClient(contextId = "remoteTaskAssigneeService", name = "ruoyi-system", path = "/remote/task-assignee", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/task-assignee")
|
||||
public interface RemoteTaskAssigneeService {
|
||||
|
||||
/**
|
||||
@@ -24,7 +22,7 @@ public interface RemoteTaskAssigneeService {
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
@PostMapping("/select-roles")
|
||||
@PostExchange("/select-roles")
|
||||
RemoteTaskAssigneeVo selectRolesByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
@@ -33,7 +31,7 @@ public interface RemoteTaskAssigneeService {
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
@PostMapping("/select-posts")
|
||||
@PostExchange("/select-posts")
|
||||
RemoteTaskAssigneeVo selectPostsByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
@@ -42,7 +40,7 @@ public interface RemoteTaskAssigneeService {
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
@PostMapping("/select-depts")
|
||||
@PostExchange("/select-depts")
|
||||
RemoteTaskAssigneeVo selectDeptsByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
/**
|
||||
@@ -51,8 +49,7 @@ public interface RemoteTaskAssigneeService {
|
||||
* @param taskQuery 查询条件
|
||||
* @return 办理人
|
||||
*/
|
||||
@PostMapping("/select-users")
|
||||
@PostExchange("/select-users")
|
||||
RemoteTaskAssigneeVo selectUsersByTaskAssigneeList(@RequestBody RemoteTaskAssigneeBo taskQuery);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
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;
|
||||
@@ -24,7 +22,8 @@ import java.util.Map;
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@FeignClient(contextId = "remoteUserService", name = "ruoyi-system", path = "/remote/user", primary = false)
|
||||
@RemoteHttpService("ruoyi-system")
|
||||
@HttpExchange("/remote/user")
|
||||
public interface RemoteUserService {
|
||||
|
||||
/**
|
||||
@@ -33,7 +32,7 @@ public interface RemoteUserService {
|
||||
* @param username 用户名
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/get-by-username")
|
||||
@GetExchange("/get-by-username")
|
||||
LoginUser getUserInfo(@RequestParam String username) throws UserException;
|
||||
|
||||
/**
|
||||
@@ -42,7 +41,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户id
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/get-by-id")
|
||||
@GetExchange("/get-by-id")
|
||||
LoginUser getUserInfo(@RequestParam Long userId) throws UserException;
|
||||
|
||||
/**
|
||||
@@ -60,7 +59,7 @@ public interface RemoteUserService {
|
||||
* @param email 邮箱
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/get-by-email")
|
||||
@GetExchange("/get-by-email")
|
||||
LoginUser getUserInfoByEmail(@RequestParam String email) throws UserException;
|
||||
|
||||
/**
|
||||
@@ -69,7 +68,7 @@ public interface RemoteUserService {
|
||||
* @param openid openid
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/get-by-openid")
|
||||
@GetExchange("/get-by-openid")
|
||||
XcxLoginUser getUserInfoByOpenid(@RequestParam String openid) throws UserException;
|
||||
|
||||
/**
|
||||
@@ -78,7 +77,7 @@ public interface RemoteUserService {
|
||||
* @param remoteUserBo 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/register-user-info")
|
||||
@PostExchange("/register-user-info")
|
||||
Boolean registerUserInfo(@RequestBody RemoteUserBo remoteUserBo) throws UserException, ServiceException;
|
||||
|
||||
/**
|
||||
@@ -87,7 +86,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户id
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/select-username-by-id")
|
||||
@GetExchange("/select-username-by-id")
|
||||
String selectUserNameById(@RequestParam Long userId);
|
||||
|
||||
/**
|
||||
@@ -96,7 +95,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户ID
|
||||
* @return 用户昵称
|
||||
*/
|
||||
@GetMapping("/select-nickname-by-id")
|
||||
@GetExchange("/select-nickname-by-id")
|
||||
String selectNicknameById(@RequestParam Long userId);
|
||||
|
||||
/**
|
||||
@@ -105,7 +104,7 @@ public interface RemoteUserService {
|
||||
* @param userIds 用户ID 多个用逗号隔开
|
||||
* @return 用户昵称
|
||||
*/
|
||||
@GetMapping("/select-nickname-by-ids")
|
||||
@GetExchange("/select-nickname-by-ids")
|
||||
String selectNicknameByIds(@RequestParam String userIds);
|
||||
|
||||
/**
|
||||
@@ -114,7 +113,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户id
|
||||
* @return 用户手机号
|
||||
*/
|
||||
@GetMapping("/select-phonenumber-by-id")
|
||||
@GetExchange("/select-phonenumber-by-id")
|
||||
String selectPhonenumberById(@RequestParam Long userId);
|
||||
|
||||
/**
|
||||
@@ -123,7 +122,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户id
|
||||
* @return 用户邮箱
|
||||
*/
|
||||
@GetMapping("/select-email-by-id")
|
||||
@GetExchange("/select-email-by-id")
|
||||
String selectEmailById(@RequestParam Long userId);
|
||||
|
||||
/**
|
||||
@@ -132,7 +131,7 @@ public interface RemoteUserService {
|
||||
* @param userId 用户ID
|
||||
* @param ip IP地址
|
||||
*/
|
||||
@PostMapping("/record-login-info")
|
||||
@PostExchange("/record-login-info")
|
||||
void recordLoginInfo(@RequestParam Long userId, @RequestParam String ip);
|
||||
|
||||
/**
|
||||
@@ -141,7 +140,7 @@ public interface RemoteUserService {
|
||||
* @param userIds 用户ids
|
||||
* @return 用户列表
|
||||
*/
|
||||
@PostMapping("/select-list-by-ids")
|
||||
@PostExchange("/select-list-by-ids")
|
||||
List<RemoteUserVo> selectListByIds(@RequestBody Collection<Long> userIds);
|
||||
|
||||
/**
|
||||
@@ -150,7 +149,7 @@ public interface RemoteUserService {
|
||||
* @param roleIds 角色ids
|
||||
* @return 用户ids
|
||||
*/
|
||||
@PostMapping("/select-user-ids-by-role-ids")
|
||||
@PostExchange("/select-user-ids-by-role-ids")
|
||||
List<Long> selectUserIdsByRoleIds(@RequestBody Collection<Long> roleIds);
|
||||
|
||||
/**
|
||||
@@ -159,7 +158,7 @@ public interface RemoteUserService {
|
||||
* @param roleIds 角色ids
|
||||
* @return 用户
|
||||
*/
|
||||
@PostMapping("/select-users-by-role-ids")
|
||||
@PostExchange("/select-users-by-role-ids")
|
||||
List<RemoteUserVo> selectUsersByRoleIds(@RequestBody Collection<Long> roleIds);
|
||||
|
||||
/**
|
||||
@@ -168,7 +167,7 @@ public interface RemoteUserService {
|
||||
* @param deptIds 部门ids
|
||||
* @return 用户
|
||||
*/
|
||||
@PostMapping("/select-users-by-dept-ids")
|
||||
@PostExchange("/select-users-by-dept-ids")
|
||||
List<RemoteUserVo> selectUsersByDeptIds(@RequestBody Collection<Long> deptIds);
|
||||
|
||||
/**
|
||||
@@ -177,7 +176,7 @@ public interface RemoteUserService {
|
||||
* @param postIds 岗位ids
|
||||
* @return 用户
|
||||
*/
|
||||
@PostMapping("/select-users-by-post-ids")
|
||||
@PostExchange("/select-users-by-post-ids")
|
||||
List<RemoteUserVo> selectUsersByPostIds(@RequestBody Collection<Long> postIds);
|
||||
|
||||
/**
|
||||
@@ -186,8 +185,7 @@ public interface RemoteUserService {
|
||||
* @param userIds 用户 ID 列表
|
||||
* @return Map,其中 key 为用户 ID,value 为对应的用户昵称
|
||||
*/
|
||||
@PostMapping("/select-user-nicks-by-ids")
|
||||
@PostExchange("/select-user-nicks-by-ids")
|
||||
Map<Long, String> selectUserNicksByIds(@RequestBody Collection<Long> userIds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package org.dromara.workflow.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.annotation.RemoteHttpService;
|
||||
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;
|
||||
@@ -21,8 +19,8 @@ import java.util.Map;
|
||||
* @Author ZETA
|
||||
* @Date 2024/6/3
|
||||
*/
|
||||
@FeignClient(contextId = "remoteWorkflowService", name = "ruoyi-workflow", path = "/remote/workflow",
|
||||
fallbackFactory = RemoteWorkflowServiceFallbackFactory.class, primary = false)
|
||||
@RemoteHttpService(value = "ruoyi-workflow", fallback = RemoteWorkflowServiceFallback.class)
|
||||
@HttpExchange("/remote/workflow")
|
||||
public interface RemoteWorkflowService {
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,7 @@ public interface RemoteWorkflowService {
|
||||
* @param businessIds 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/delete-instance")
|
||||
@PostExchange("/delete-instance")
|
||||
boolean deleteInstance(@RequestBody List<String> businessIds);
|
||||
|
||||
/**
|
||||
@@ -40,7 +38,7 @@ public interface RemoteWorkflowService {
|
||||
* @param taskId 任务id
|
||||
* @return 状态
|
||||
*/
|
||||
@GetMapping("/business-status-by-task-id")
|
||||
@GetExchange("/business-status-by-task-id")
|
||||
String getBusinessStatusByTaskId(@RequestParam Long taskId);
|
||||
|
||||
/**
|
||||
@@ -49,7 +47,7 @@ public interface RemoteWorkflowService {
|
||||
* @param businessId 业务id
|
||||
* @return 状态
|
||||
*/
|
||||
@GetMapping("/business-status")
|
||||
@GetExchange("/business-status")
|
||||
String getBusinessStatus(@RequestParam String businessId);
|
||||
|
||||
/**
|
||||
@@ -58,7 +56,7 @@ public interface RemoteWorkflowService {
|
||||
* @param instanceId 流程实例id
|
||||
* @param variable 流程变量
|
||||
*/
|
||||
@PostMapping("/set-variable")
|
||||
@PostExchange("/set-variable")
|
||||
void setVariable(@RequestParam Long instanceId, @RequestBody Map<String, Object> variable);
|
||||
|
||||
/**
|
||||
@@ -66,7 +64,7 @@ public interface RemoteWorkflowService {
|
||||
*
|
||||
* @param instanceId 流程实例id
|
||||
*/
|
||||
@GetMapping("/instance-variable")
|
||||
@GetExchange("/instance-variable")
|
||||
Map<String, Object> instanceVariable(@RequestParam Long instanceId);
|
||||
|
||||
/**
|
||||
@@ -75,7 +73,7 @@ public interface RemoteWorkflowService {
|
||||
* @param businessId 业务id
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/instance-id-by-business-id")
|
||||
@GetExchange("/instance-id-by-business-id")
|
||||
Long getInstanceIdByBusinessId(@RequestParam String businessId);
|
||||
|
||||
/**
|
||||
@@ -84,7 +82,7 @@ public interface RemoteWorkflowService {
|
||||
* @param startProcess 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/start-workflow")
|
||||
@PostExchange("/start-workflow")
|
||||
RemoteStartProcessReturn startWorkFlow(@RequestBody RemoteStartProcess startProcess);
|
||||
|
||||
/**
|
||||
@@ -93,7 +91,7 @@ public interface RemoteWorkflowService {
|
||||
* @param completeTask 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/complete-task")
|
||||
@PostExchange("/complete-task")
|
||||
boolean completeTask(@RequestBody RemoteCompleteTask completeTask);
|
||||
|
||||
|
||||
@@ -104,7 +102,7 @@ public interface RemoteWorkflowService {
|
||||
* @param message 办理意见
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/complete-task-simple")
|
||||
@PostExchange("/complete-task-simple")
|
||||
boolean completeTask(@RequestParam Long taskId, @RequestParam String message);
|
||||
|
||||
/**
|
||||
@@ -113,8 +111,7 @@ public interface RemoteWorkflowService {
|
||||
* @param startProcess 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/start-complete-task")
|
||||
@PostExchange("/start-complete-task")
|
||||
boolean startCompleteTask(@RequestBody RemoteStartProcess startProcess);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
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<String> 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<String, Object> variable) {
|
||||
log.warn("服务调用异常 -> 降级处理");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +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 org.springframework.cloud.openfeign.FallbackFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工作流服务 fallback factory.
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
public class RemoteWorkflowServiceFallbackFactory implements FallbackFactory<RemoteWorkflowService> {
|
||||
|
||||
@Override
|
||||
public RemoteWorkflowService create(Throwable cause) {
|
||||
return new RemoteWorkflowService() {
|
||||
@Override
|
||||
public boolean deleteInstance(List<String> 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<String, Object> variable) {
|
||||
log.warn("工作流服务调用失败, 已触发 fallback", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -31,32 +31,15 @@
|
||||
<artifactId>ruoyi-common-satoken</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-mybatis</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.fory</groupId>
|
||||
<artifactId>fory-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
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;
|
||||
@@ -20,13 +18,8 @@ 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 {};
|
||||
}
|
||||
|
||||
@@ -1,35 +1,38 @@
|
||||
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.log.support.RemoteHttpFeignLogger;
|
||||
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.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.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
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;
|
||||
@@ -40,24 +43,26 @@ import java.nio.charset.StandardCharsets;
|
||||
* 这里把运行时几条链路接起来:
|
||||
* 1. Consumer 发请求前透传认证头和 Seata XID
|
||||
* 2. 远程非 2xx 响应统一转成 ServiceException
|
||||
* 3. 打开请求日志时,为 consumer/provider 两侧挂统一日志
|
||||
* 3. 打开请求日志时,为 consumer/provider 两侧挂日志能力
|
||||
* 4. 远程代理失败时按接口声明触发 fallback
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@AutoConfiguration
|
||||
@EnableFeignClients(basePackages = "org.dromara")
|
||||
@Import(RemoteHttpServiceRegistrar.class)
|
||||
@EnableConfigurationProperties(RemoteHttpProperties.class)
|
||||
public class RemoteHttpAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public static BeanDefinitionRegistryPostProcessor remoteHttpControllerProxyCompatibilityPostProcessor() {
|
||||
public static BeanFactoryPostProcessor remoteHttpControllerProxyCompatibilityPostProcessor() {
|
||||
return new RemoteHttpInfrastructurePostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestInterceptor remoteHttpRequestInterceptor() {
|
||||
return requestTemplate -> {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@Bean("remoteHttpHeaderInterceptor")
|
||||
public ClientHttpRequestInterceptor remoteHttpHeaderInterceptor() {
|
||||
return (request, body, execution) -> {
|
||||
HttpHeaders headers = request.getHeaders();
|
||||
HttpServletRequest currentRequest = ServletUtils.getRequest();
|
||||
if (currentRequest != null) {
|
||||
String authorization = currentRequest.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
@@ -71,29 +76,35 @@ public class RemoteHttpAutoConfiguration {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
relaySeataXid(headers);
|
||||
headers.forEach((key, values) -> values.forEach(value -> requestTemplate.header(key, value)));
|
||||
return execution.execute(request, body);
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Logger remoteHttpFeignLogger(
|
||||
public RestClientHttpServiceGroupConfigurer remoteHttpServiceGroupConfigurer(
|
||||
ClientHttpRequestInterceptor remoteHttpHeaderInterceptor,
|
||||
RemoteHttpLogSupport remoteHttpLogSupport) {
|
||||
return new RemoteHttpFeignLogger(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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Logger.Level remoteHttpFeignLoggerLevel() {
|
||||
return Logger.Level.BASIC;
|
||||
public RemoteHttpFallbackProxyPostProcessor remoteHttpFallbackProxyPostProcessor() {
|
||||
return new RemoteHttpFallbackProxyPostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ErrorDecoder remoteHttpErrorDecoder() {
|
||||
return (methodKey, response) -> buildServiceException(response.status(), response.reason(), readResponseBody(response));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RemoteHttpLogSupport remoteHttpLogSupport() {
|
||||
return new RemoteHttpLogSupport();
|
||||
public RemoteHttpLogSupport remoteHttpLogSupport(RemoteHttpProperties properties) {
|
||||
return new RemoteHttpLogSupport(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -122,85 +133,50 @@ public class RemoteHttpAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private String readResponseBody(Response response) {
|
||||
if (response.body() == null) {
|
||||
return null;
|
||||
}
|
||||
private String readResponseBody(org.springframework.http.client.ClientHttpResponse response) {
|
||||
try {
|
||||
return StreamUtils.copyToString(response.body().asInputStream(), StandardCharsets.UTF_8);
|
||||
return StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
log.debug("read remote response body failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceException buildServiceException(int statusCode, String statusText, String responseBody) {
|
||||
private void throwServiceException(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 new ServiceException(StringUtils.defaultIfBlank(statusText, "远程服务调用失败"), statusCode);
|
||||
return;
|
||||
}
|
||||
if (result != null && StringUtils.isNotBlank(result.getMsg())) {
|
||||
return new ServiceException(result.getMsg(), result.getCode());
|
||||
throw 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, "远程服务调用失败");
|
||||
return new ServiceException(message, statusCode);
|
||||
throw new ServiceException(message, statusCode);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
private static final class RemoteHttpInfrastructurePostProcessor implements BeanFactoryPostProcessor {
|
||||
|
||||
@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;
|
||||
@@ -210,5 +186,48 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
// 本地注入 provider bean 时再回退到接口上的 Spring MVC 映射注解。
|
||||
HttpMethod httpMethod = resolveHttpMethod(request, remoteInterface, targetClass, method);
|
||||
String path = resolvePath(request, remoteInterface, targetClass, method);
|
||||
// 本地短路调用时再回退到接口上的 @HttpExchange 注解。
|
||||
HttpMethod httpMethod = resolveHttpMethod(request, remoteInterface, method);
|
||||
String path = resolvePath(request, remoteInterface, method);
|
||||
this.logSupport.logRequest(RemoteHttpLogSupport.PROVIDER, httpMethod, path, arguments);
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
@@ -55,25 +55,22 @@ public class RemoteHttpProviderLogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpMethod resolveHttpMethod(HttpServletRequest request, Class<?> remoteInterface, Class<?> targetClass, Method method) {
|
||||
private HttpMethod resolveHttpMethod(HttpServletRequest request, Class<?> remoteInterface, Method method) {
|
||||
if (request != null && StringUtils.hasText(request.getMethod())) {
|
||||
return HttpMethod.valueOf(request.getMethod());
|
||||
}
|
||||
RequestMapping methodMapping = resolveMethodMapping(remoteInterface, method);
|
||||
if (methodMapping != null && methodMapping.method().length > 0) {
|
||||
return HttpMethod.valueOf(methodMapping.method()[0].name());
|
||||
HttpExchange methodExchange = resolveMethodExchange(remoteInterface, method);
|
||||
if (methodExchange != null && StringUtils.hasText(methodExchange.method())) {
|
||||
return HttpMethod.valueOf(methodExchange.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());
|
||||
HttpExchange typeExchange = resolveTypeExchange(remoteInterface);
|
||||
if (typeExchange != null && StringUtils.hasText(typeExchange.method())) {
|
||||
return HttpMethod.valueOf(typeExchange.method());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolvePath(HttpServletRequest request, Class<?> remoteInterface, Class<?> targetClass, Method method) {
|
||||
private String resolvePath(HttpServletRequest request, Class<?> remoteInterface, Method method) {
|
||||
if (request != null) {
|
||||
String requestUri = request.getRequestURI();
|
||||
if (StringUtils.hasText(requestUri)) {
|
||||
@@ -84,11 +81,8 @@ public class RemoteHttpProviderLogAspect {
|
||||
return requestUri + '?' + queryString;
|
||||
}
|
||||
}
|
||||
String typePath = extractPath(resolveTypeMapping(remoteInterface));
|
||||
if (!StringUtils.hasText(typePath)) {
|
||||
typePath = extractPath(resolveTypeMapping(targetClass));
|
||||
}
|
||||
String methodPath = extractPath(resolveMethodMapping(remoteInterface, method));
|
||||
String typePath = extractPath(resolveTypeExchange(remoteInterface));
|
||||
String methodPath = extractPath(resolveMethodExchange(remoteInterface, method));
|
||||
if (!StringUtils.hasText(typePath)) {
|
||||
return methodPath;
|
||||
}
|
||||
@@ -101,7 +95,7 @@ public class RemoteHttpProviderLogAspect {
|
||||
|
||||
private Class<?> resolveRemoteInterface(Class<?> targetClass, Method method) {
|
||||
for (Class<?> interfaceType : targetClass.getInterfaces()) {
|
||||
if (interfaceType.isAnnotationPresent(FeignClient.class)
|
||||
if (interfaceType.isAnnotationPresent(RemoteHttpService.class)
|
||||
&& org.springframework.util.ReflectionUtils.findMethod(interfaceType, method.getName(), method.getParameterTypes()) != null) {
|
||||
return interfaceType;
|
||||
}
|
||||
@@ -109,14 +103,14 @@ public class RemoteHttpProviderLogAspect {
|
||||
return null;
|
||||
}
|
||||
|
||||
private RequestMapping resolveTypeMapping(Class<?> remoteInterface) {
|
||||
private HttpExchange resolveTypeExchange(Class<?> remoteInterface) {
|
||||
if (remoteInterface == null) {
|
||||
return null;
|
||||
}
|
||||
return AnnotatedElementUtils.findMergedAnnotation(remoteInterface, RequestMapping.class);
|
||||
return AnnotatedElementUtils.findMergedAnnotation(remoteInterface, HttpExchange.class);
|
||||
}
|
||||
|
||||
private RequestMapping resolveMethodMapping(Class<?> remoteInterface, Method method) {
|
||||
private HttpExchange resolveMethodExchange(Class<?> remoteInterface, Method method) {
|
||||
if (remoteInterface == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -124,18 +118,18 @@ public class RemoteHttpProviderLogAspect {
|
||||
if (interfaceMethod == null) {
|
||||
return null;
|
||||
}
|
||||
return AnnotatedElementUtils.findMergedAnnotation(interfaceMethod, RequestMapping.class);
|
||||
return AnnotatedElementUtils.findMergedAnnotation(interfaceMethod, HttpExchange.class);
|
||||
}
|
||||
|
||||
private String extractPath(RequestMapping mapping) {
|
||||
if (mapping == null) {
|
||||
private String extractPath(HttpExchange exchange) {
|
||||
if (exchange == null) {
|
||||
return null;
|
||||
}
|
||||
if (mapping.path().length > 0 && StringUtils.hasText(mapping.path()[0])) {
|
||||
return mapping.path()[0];
|
||||
if (StringUtils.hasText(exchange.url())) {
|
||||
return exchange.url();
|
||||
}
|
||||
if (mapping.value().length > 0 && StringUtils.hasText(mapping.value()[0])) {
|
||||
return mapping.value()[0];
|
||||
if (StringUtils.hasText(exchange.value())) {
|
||||
return exchange.value();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.dromara.common.http.log.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
/**
|
||||
* 请求日志级别.
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public enum RequestLogEnum {
|
||||
|
||||
/**
|
||||
* 基础信息.
|
||||
*/
|
||||
INFO,
|
||||
|
||||
/**
|
||||
* 参数信息.
|
||||
*/
|
||||
PARAM,
|
||||
|
||||
/**
|
||||
* 全量信息.
|
||||
*/
|
||||
FULL
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
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 <T> @Nullable T exchangeForBody(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
|
||||
return invoke(requestValues, () -> super.exchangeForBody(requestValues, bodyType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> exchangeForBodilessEntity(HttpRequestValues requestValues) {
|
||||
return invoke(requestValues, () -> super.exchangeForBodilessEntity(requestValues));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ResponseEntity<T> exchangeForEntity(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
|
||||
return invoke(requestValues, () -> super.exchangeForEntity(requestValues, bodyType));
|
||||
}
|
||||
|
||||
private <T> T invoke(HttpRequestValues requestValues, ThrowingSupplier<T> 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<String, String> uriVariables = requestValues.getUriVariables();
|
||||
String path = uriTemplate;
|
||||
if (uriVariables != null) {
|
||||
for (Map.Entry<String, String> entry : uriVariables.entrySet()) {
|
||||
path = path.replace("{" + entry.getKey() + "}", String.valueOf(entry.getValue()));
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ThrowingSupplier<T> {
|
||||
|
||||
T get() throws Throwable;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,19 @@
|
||||
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 日志支持.
|
||||
*
|
||||
@@ -14,22 +24,50 @@ import org.springframework.util.StringUtils;
|
||||
* @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);
|
||||
log.info("HTTP - 服务调用: {}", baseLog);
|
||||
if (properties.getLogLevel() == RequestLogEnum.INFO) {
|
||||
log.info("HTTP - 服务调用: {}", baseLog);
|
||||
return;
|
||||
}
|
||||
log.info("HTTP - 服务调用: {},Parameter={}", baseLog, formatArguments(arguments));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -44,4 +82,51 @@ 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<Object, Object> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
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<String> scanPackagePatterns = new LinkedHashSet<>(resolveConfiguredScanPackages());
|
||||
if (scanPackagePatterns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<String> scanBasePackages = resolveScanBasePackages(scanPackagePatterns);
|
||||
if (scanBasePackages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 先找出当前服务自己已经提供的远程接口,后面这些接口不再注册 HTTP client。
|
||||
Set<String> localServiceTypes = resolveLocalServiceTypes(scanBasePackages, scanPackagePatterns);
|
||||
MultiValueMap<String, String> groupedServices = resolveRemoteHttpServices(scanBasePackages, scanPackagePatterns, localServiceTypes);
|
||||
groupedServices.forEach((serviceId, classNames) ->
|
||||
registry.forGroup(serviceId).registerTypeNames(classNames.toArray(String[]::new)));
|
||||
}
|
||||
|
||||
private MultiValueMap<String, String> resolveRemoteHttpServices(Set<String> basePackages, Set<String> scanPackagePatterns,
|
||||
Set<String> localServiceTypes) {
|
||||
MultiValueMap<String, String> 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<String> resolveLocalServiceTypes(Set<String> basePackages, Set<String> scanPackagePatterns) {
|
||||
MultiValueMap<String, String> 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<AnnotatedBeanDefinition> scanCandidateComponents(Set<String> basePackages,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
ClassPathScanningCandidateComponentProvider scanner = createScanner(annotationType);
|
||||
List<AnnotatedBeanDefinition> 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<? extends Annotation> 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<String, Object> 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<String> 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<String> resolveScanBasePackages(Set<String> scanPackagePatterns) {
|
||||
Set<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
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<String, Object> 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<String, Object> 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<String, Object>) map);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("数据权限上下文反序列化失败");
|
||||
}
|
||||
throw new ServiceException("数据权限上下文格式非法");
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
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<String, Object>) previousContext);
|
||||
request.removeAttribute(CONTEXT_ATTRIBUTE);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
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<String, Object> snapshotContext() {
|
||||
return new LinkedHashMap<>(DataPermissionHelper.getContext());
|
||||
}
|
||||
|
||||
public static void replaceContext(Map<String, Object> context) {
|
||||
Map<String, Object> currentContext = DataPermissionHelper.getContext();
|
||||
currentContext.clear();
|
||||
if (context != null && !context.isEmpty()) {
|
||||
currentContext.putAll(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
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 包装器.
|
||||
*
|
||||
* <p>仅包装注册器生成的远程 HTTP 代理 Bean。代理调用报错时,
|
||||
* 按接口上声明的 fallback 实现兜底,不处理本地 provider Bean。
|
||||
*
|
||||
* <p>这里故意保持和之前 mock/stub 类似的简单约束:
|
||||
* fallback 必须实现接口本身,且方法签名与接口保持一致。</p>
|
||||
*
|
||||
* @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 {
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1 @@
|
||||
org.dromara.common.http.config.RemoteHttpAutoConfiguration
|
||||
org.dromara.common.http.config.RemoteHttpDataPermissionAutoConfiguration
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.fory</groupId>
|
||||
<artifactId>fory-core</artifactId>
|
||||
<version>0.13.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/file")
|
||||
@RemoteServiceController
|
||||
public class RemoteFileServiceImpl implements RemoteFileService {
|
||||
|
||||
private final ISysOssService sysOssService;
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.dromara.resource.api.RemoteMailService;
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/mail")
|
||||
@RemoteServiceController
|
||||
public class RemoteMailServiceImpl implements RemoteMailService {
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/message")
|
||||
@RemoteServiceController
|
||||
public class RemoteMessageServiceImpl implements RemoteMessageService {
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/inner/remote/resource/sms")
|
||||
@RemoteServiceController
|
||||
public class RemoteSmsServiceImpl implements RemoteSmsService {
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.dromara.system.service.ISysClientService;
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/client")
|
||||
@RemoteServiceController
|
||||
public class RemoteClientServiceImpl implements RemoteClientService {
|
||||
|
||||
private final ISysClientService sysClientService;
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/config")
|
||||
@RemoteServiceController
|
||||
public class RemoteConfigServiceImpl implements RemoteConfigService {
|
||||
|
||||
private final ISysConfigService configService;
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.List;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/data-scope")
|
||||
@RemoteServiceController
|
||||
public class RemoteDataScopeServiceImpl implements RemoteDataScopeService {
|
||||
|
||||
private final SysRoleDeptMapper roleDeptMapper;
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/dept")
|
||||
@RemoteServiceController
|
||||
public class RemoteDeptServiceImpl implements RemoteDeptService {
|
||||
|
||||
private final ISysDeptService deptService;
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.List;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/dict")
|
||||
@RemoteServiceController
|
||||
public class RemoteDictServiceImpl implements RemoteDictService {
|
||||
|
||||
private final ISysDictTypeService sysDictTypeService;
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/log")
|
||||
@RemoteServiceController
|
||||
public class RemoteLogServiceImpl implements RemoteLogService {
|
||||
|
||||
private final ISysOperLogService operLogService;
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Set;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/permission")
|
||||
@RemoteServiceController
|
||||
public class RemotePermissionServiceImpl implements RemotePermissionService {
|
||||
|
||||
private final ISysPermissionService permissionService;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Map;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/post")
|
||||
@RemoteServiceController
|
||||
public class RemotePostServiceImpl implements RemotePostService {
|
||||
|
||||
private final SysPostMapper postMapper;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Map;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/role")
|
||||
@RemoteServiceController
|
||||
public class RemoteRoleServiceImpl implements RemoteRoleService {
|
||||
|
||||
private final SysRoleMapper roleMapper;
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.List;
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/social")
|
||||
@RemoteServiceController
|
||||
public class RemoteSocialServiceImpl implements RemoteSocialService {
|
||||
|
||||
private final ISysSocialService sysSocialService;
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.Map;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/task-assignee")
|
||||
@RemoteServiceController
|
||||
public class RemoteTaskAssigneeServiceImpl implements RemoteTaskAssigneeService {
|
||||
|
||||
// 上级Service注入下级Service 其他Service永远不可能注入当前类 避免循环注入
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.*;
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RemoteServiceController(path = "/remote/user")
|
||||
@RemoteServiceController
|
||||
public class RemoteUserServiceImpl implements RemoteUserService {
|
||||
|
||||
private final ISysUserService userService;
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
* @Author ZETA
|
||||
* @Date 2024/6/3
|
||||
*/
|
||||
@RemoteServiceController(path = "/remote/workflow")
|
||||
@RemoteServiceController
|
||||
@RequiredArgsConstructor
|
||||
public class RemoteWorkflowServiceImpl implements RemoteWorkflowService {
|
||||
|
||||
|
||||
@@ -9,10 +9,20 @@ server:
|
||||
# 最大线程数
|
||||
max: 256
|
||||
|
||||
remote:
|
||||
http:
|
||||
# 远程接口扫描范围,支持 Ant 风格包路径
|
||||
scan-packages:
|
||||
- org.dromara.**.api
|
||||
# 全局请求log
|
||||
request-log: true
|
||||
# info 基础信息 param 参数信息 full 全部
|
||||
log-level: info
|
||||
|
||||
spring:
|
||||
http:
|
||||
clients:
|
||||
# Spring HTTP 客户端默认超时配置,供非 Feign 客户端复用
|
||||
# 默认 client HTTP 请求超时,供 RestClient / HTTP Service Client 复用
|
||||
connect-timeout: 3s
|
||||
read-timeout: 10s
|
||||
imperative:
|
||||
@@ -56,9 +66,6 @@ spring:
|
||||
# 允许对象忽略json中不存在的属性
|
||||
fail_on_unknown_properties: false
|
||||
cloud:
|
||||
openfeign:
|
||||
circuitbreaker:
|
||||
enabled: true
|
||||
inetutils:
|
||||
# 指定全局使用ip网段
|
||||
preferred-networks:
|
||||
|
||||
Reference in New Issue
Block a user