main
lensfrex 1 year ago
parent be03878e94
commit ea314be257
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 2
      .gitignore
  2. 2
      .idea/encodings.xml
  3. 36
      .idea/inspectionProfiles/Project_Default.xml
  4. 19
      README.md
  5. 2
      backend-main/backend-data/src/main/java/cn/wustlinghang/main/data/Main.java
  6. 20
      backend-main/backend-web/src/main/java/cn/wustlinghang/internal/api/v1/FrpPluginHandler.java
  7. 14
      backend-main/backend-web/src/main/java/cn/wustlinghang/internal/api/v1/response/FrpPluginResponse.java
  8. 15
      backend-main/backend-web/src/main/java/cn/wustlinghang/main/web/Main.java
  9. 13
      backend-main/backend-web/src/main/java/cn/wustlinghang/main/web/api/v2/undergrade/UndergradController.java
  10. 10
      backend-main/backend-web/src/main/resources/application.yml
  11. 13
      backend-main/pom.xml
  12. 15
      common/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/response/RpcCommonResponseCode.java
  13. 4
      common/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/response/RpcResponse.java
  14. 28
      common/src/main/java/cn/wustlinghang/wusthelper/main/response/Response.java
  15. 28
      common/src/main/java/cn/wustlinghang/wusthelper/main/response/ResponseCode.java
  16. 2
      external-library/mywust
  17. 1
      external-library/pom.xml
  18. 38
      external-library/rpc-frp-consul/.gitignore
  19. 42
      external-library/rpc-frp-consul/pom.xml
  20. 92
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/FrpConsulRegister.java
  21. 63
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/client/ConsulClient.java
  22. 96
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/client/FrpcClient.java
  23. 12
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/config/FrpConfig.java
  24. 12
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/config/RegisterConfig.java
  25. 12
      external-library/rpc-frp-consul/src/main/java/cn/wustlinghang/wusthelper/internal/rpc/entity/RegisterRequestBody.java
  26. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/CookieApi.java
  27. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/CourseTableApi.java
  28. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/ScoreApi.java
  29. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/StudentInfoApi.java
  30. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/TrainingPlanApi.java
  31. 8
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/BaseExceptionHandler.java
  32. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/DefaultExceptionHandler.java
  33. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/IOExceptionHandler.java
  34. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/ParseExceptionHandler.java
  35. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/RpcExceptionHandler.java
  36. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/ValidationExceptionHandler.java
  37. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/handler/WebApplicationExceptionHandler.java
  38. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  39. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/BookCoverImageApi.java
  40. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/BookDetailApi.java
  41. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/BookHoldingApi.java
  42. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/CookieApi.java
  43. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/CurrentLoanApi.java
  44. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/LoanHistoryApi.java
  45. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/OverdueSoonApi.java
  46. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/SearchApi.java
  47. 8
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/BaseExceptionHandler.java
  48. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/DefaultExceptionHandler.java
  49. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/IOExceptionHandler.java
  50. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/ParseExceptionHandler.java
  51. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/RpcExceptionHandler.java
  52. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/ValidationExceptionHandler.java
  53. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/handler/WebApplicationExceptionHandler.java
  54. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  55. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/CookieApi.java
  56. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/CourseTableApi.java
  57. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/ScoreApi.java
  58. 8
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/BaseExceptionHandler.java
  59. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/DefaultExceptionHandler.java
  60. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/IOExceptionHandler.java
  61. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/ParseExceptionHandler.java
  62. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/RpcExceptionHandler.java
  63. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/ValidationExceptionHandler.java
  64. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/handler/WebApplicationExceptionHandler.java
  65. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  66. 10
      sub-services/undergrad/.flattened-pom.xml
  67. 1
      sub-services/undergrad/pom.xml
  68. 16
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/Main.java
  69. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/CookieApi.java
  70. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/CourseTableApi.java
  71. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/CreditStatusApi.java
  72. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/ExamActivitiesApi.java
  73. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/ExamDelayApplicationApi.java
  74. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/ScoreApi.java
  75. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/StudentInfoApi.java
  76. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/TrainingPlanApi.java
  77. 8
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/BaseExceptionHandler.java
  78. 6
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/DefaultExceptionHandler.java
  79. 6
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/IOExceptionHandler.java
  80. 6
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/ParseExceptionHandler.java
  81. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/RpcExceptionHandler.java
  82. 6
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/ValidationExceptionHandler.java
  83. 2
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/handler/WebApplicationExceptionHandler.java
  84. 4
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/http/v1/interceptor/ResponseWrapperInterceptor.java
  85. 107
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/FrpConsulRegister.java
  86. 60
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/client/ConsulClient.java
  87. 100
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/client/FrpcClient.java
  88. 22
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/config/FrpConfig.java
  89. 18
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/config/RpcConfig.java
  90. 13
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/entity/RegisterRequestBody.java
  91. 14
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/rpc/health/HealthCheck.java
  92. 9
      sub-services/undergrad/src/main/resources/application.properties

2
.gitignore vendored

@ -36,3 +36,5 @@ build/
### Mac OS ###
.DS_Store
.env

@ -27,6 +27,8 @@
<file url="file://$PROJECT_DIR$/external-library/mywust/mywust-util/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/mywust/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/mywust/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/rpc-frp-consul/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/rpc-frp-consul/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/external-library/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />

@ -0,0 +1,36 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredUrls">
<list>
<option value="http://localhost" />
<option value="http://127.0.0.1" />
<option value="http://0.0.0.0" />
<option value="http://www.w3.org/" />
<option value="http://json-schema.org/draft" />
<option value="http://java.sun.com/" />
<option value="http://xmlns.jcp.org/" />
<option value="http://javafx.com/javafx/" />
<option value="http://javafx.com/fxml" />
<option value="http://maven.apache.org/xsd/" />
<option value="http://maven.apache.org/POM/" />
<option value="http://www.springframework.org/schema/" />
<option value="http://www.springframework.org/tags" />
<option value="http://www.springframework.org/security/tags" />
<option value="http://www.thymeleaf.org" />
<option value="http://www.jboss.org/j2ee/schema/" />
<option value="http://www.jboss.com/xml/ns/" />
<option value="http://www.ibm.com/webservices/xsd" />
<option value="http://activemq.apache.org/schema/" />
<option value="http://schema.cloudfoundry.org/spring/" />
<option value="http://schemas.xmlsoap.org/" />
<option value="http://cxf.apache.org/schemas/" />
<option value="http://primefaces.org/ui" />
<option value="http://tiles.apache.org/" />
<option value="http://" />
</list>
</option>
</inspection_tool>
</profile>
</component>

@ -4,7 +4,9 @@
应该是第三代后端了吧。
新的重写过的后端,其实在这版正式出来之前已经有很多个实验性的原型版本了,但是都因为效果不如意胎死腹中给砍了,没有继续写下去(其实这个readme也是曾经最早的一个原型版本改来的)
新的重写过的后端,其实在这版正式出来之前已经有很多个实验性的原型版本了,用了各种不同的技术,包括grpc,dubbo等等,但是都因为效果不如意或者不合适胎死腹中给砍了,没有继续写下去(其实这个readme也是曾经最早的一个原型版本改来的)
现在的这个版本应该差不多了,是时候放上来了。
这代后端结构与前面的有很大不同,使用了真·多模块的方式运行部署,部分独立模块以不同的程序运行,子模块部署在内网时,可以自动注册frpc进行服务远程转发,主服务和子服务通过http进行通信调用,各模块可以部署在不同的服务器或容器中,当然,也可以挤在一起跑。
@ -23,7 +25,8 @@
包管理和构建:
Maven 3.8.2+
- 后续可能会看情况转用Gradle
- *后续可能会看情况转用Gradle*
Java版本:
Java 17+
@ -32,7 +35,7 @@ Java 17+
## 项目模块结构
### agent-service
详见[doc](/doc)
---
@ -40,10 +43,18 @@ Java 17+
---
## 文档
## API文档
详见[doc](/doc)
---
## 构建
---
## 运行
---
就先这样吧,手累了

@ -1,4 +1,4 @@
package cn.wustlinghang.data;
package cn.wustlinghang.main.data;
public class Main {
public static void main(String[] args) {

@ -0,0 +1,20 @@
package cn.wustlinghang.internal.api.v1;
import cn.wustlinghang.internal.api.v1.response.FrpPluginResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/internal/frp")
public class FrpPluginHandler {
@RequestMapping("/handler")
public FrpPluginResponse handle(String request) {
log.info(request);
return FrpPluginResponse.builder()
.reject(false)
.unchange(true)
.build();
}
}

@ -0,0 +1,14 @@
package cn.wustlinghang.internal.api.v1.response;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class FrpPluginResponse {
private boolean reject;
private boolean unchange;
// private String rejectReason;
}

@ -0,0 +1,15 @@
package cn.wustlinghang.main.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
}

@ -0,0 +1,13 @@
package cn.wustlinghang.main.web.api.v2.undergrade;
import cn.wustlinghang.wusthelper.main.response.Response;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/jwc")
public class UndergradController {
public Response<String> login() {
return Response.success("");
}
}

@ -0,0 +1,10 @@
# 服务端配置
# 密码/密钥/内部地址『禁止』写在此处或其他git能检测到的地方
# 具体数值由运维填写在.env文件中,不能添加到git仓库中
spring:
config:
import: optional:file:.env[.properties]
server:
port: ${RUN_PORT}

@ -22,4 +22,17 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.wustlinghang.mywust</groupId>
<artifactId>mywust-common</artifactId>
<version>${mywust.version}</version>
</dependency>
</dependencies>
</project>

@ -4,7 +4,7 @@
package cn.wustlinghang.wusthelper.internal.rpc.response;
public enum ResponseCode {
public enum RpcCommonResponseCode {
SUCCESS(20000, "成功"),
REQUEST_TOO_FAST(20001, "技能冷却中..."),
INVALID_REQUEST(30000, "非法请求"),
@ -13,22 +13,13 @@ public enum ResponseCode {
TOKEN_EXPIRED(40001, "token过期"),
TOKEN_INVALID(40002, "token无效"),
SERVER_INTERNAL_ERROR(50000, "服务器内部错误"),
API_NOT_IMPLEMENT(0, "接口未实现"),
STUDENT_ID_DOES_NOT_EXISTS(60001,"学生学号不存在"),
USER_WAS_BANNED_PUBLISH(60201, "用户被禁止发布告示信息"),
IMAGE_FORMAT_WORN(60202, "上传的图片格式有误"),
NOTICE_WAS_INTERCEPT(60203, "消息被系统拦截发布"),
USER_DOES_NOT_MATCH_PUBLISHER(60301, "请求用户与告示发表者不匹配"),
REQUEST_FILE_DOES_NOT_EXIST(60701, "请求的文件不存在");
API_NOT_IMPLEMENT(0, "接口未实现"),;
private final int code;
private final String message;
ResponseCode(int code, String message) {
RpcCommonResponseCode(int code, String message) {
this.code = code;
this.message = message;
}

@ -2,7 +2,7 @@ package cn.wustlinghang.wusthelper.internal.rpc.response;
public record RpcResponse<T>(int code, String msg, T data) {
public static <T> RpcResponse<T> success(T data) {
return new RpcResponse<>(ResponseCode.SUCCESS.getCode(), "ok", data);
return new RpcResponse<>(RpcCommonResponseCode.SUCCESS.getCode(), "ok", data);
}
public static <T> RpcResponse<T> success() {
@ -13,7 +13,7 @@ public record RpcResponse<T>(int code, String msg, T data) {
return new RpcResponse<>(code, message, null);
}
public static <T> RpcResponse<T> error(ResponseCode code) {
public static <T> RpcResponse<T> error(RpcCommonResponseCode code) {
return error(code.getCode(), code.getMessage());
}
}

@ -0,0 +1,28 @@
package cn.wustlinghang.wusthelper.main.response;
/**
* 通用的响应
*
* @param code 响应码
* @param msg 响应信息
* @param data 响应数据
* @param <T> data的类型
*/
public record Response<T>(int code, String msg, T data) {
public static <T> Response<T> success(T data) {
return new Response<>(ResponseCode.SUCCESS.getCode(), "ok", data);
}
public static <T> Response<T> success() {
return success(null);
}
public static <T> Response<T> error(int code, String message) {
return new Response<>(code, message, null);
}
public static <T> Response<T> error(ResponseCode code) {
return error(code.getCode(), code.getMessage());
}
}

@ -0,0 +1,28 @@
/*
* Class created by lensfrex.
*/
package cn.wustlinghang.wusthelper.main.response;
public enum ResponseCode {
SUCCESS(0, "成功"),
SERVER_INTERNAL_ERROR(-2, "服务器内部错误"),
API_NOT_IMPLEMENT(-1, "接口未实现");
private final int code;
private final String message;
ResponseCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}

@ -1 +1 @@
Subproject commit 965562b69e35d445fb5c58b2e2afd9cdf27d3146
Subproject commit 736dc78d1b9e64124474cee98c5db6e8212fa096

@ -14,5 +14,6 @@
<packaging>pom</packaging>
<modules>
<module>mywust</module>
<module>rpc-frp-consul</module>
</modules>
</project>

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>external-library</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rpc-frp-consul</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson.version>2.15.2</jackson.version>
<ini4j.version>0.5.4</ini4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.mywust</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>${mywust.version}</version>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>${ini4j.version}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,92 @@
package cn.wustlinghang.wusthelper.internal.rpc;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.rpc.client.ConsulClient;
import cn.wustlinghang.wusthelper.internal.rpc.client.FrpcClient;
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig;
import cn.wustlinghang.wusthelper.internal.rpc.config.RegisterConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FrpConsulRegister {
private final String serviceId;
private final RegisterConfig registerConfig;
private final FrpcClient frpcClientClient;
private final ConsulClient consulClient;
private boolean registered = false;
public FrpConsulRegister(RegisterConfig registerConfig, FrpConfig frpConfig,
Requester requester, ObjectMapper objectMapper) {
this.serviceId = RandomUtil.randomString(8);
this.registerConfig = registerConfig;
this.frpcClientClient = new FrpcClient(frpConfig, requester, objectMapper);
this.consulClient = new ConsulClient(this.serviceId, registerConfig, objectMapper, requester);
}
public void register() {
ThreadUtil.execute(() -> {
try {
log.info("连接frp并注册consul...");
this.doRegister();
log.info("注册完毕");
} catch (Exception e) {
log.warn("注册服务时发生异常:", e);
log.warn("不进行转发注册,直接服务");
}
});
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown, "ShutdownHookThread"));
}
private void onShutdown() {
try {
if (this.registered) {
log.info("注销服务...");
this.consulClient.deregister();
this.frpcClientClient.removeProxy();
this.registered = false;
log.info("服务注销完毕");
}
} catch (Exception e) {
log.warn("注销服务时发生异常:", e);
}
}
private void doRegister() throws Exception {
frpcClientClient.addFrpProxy(
registerConfig.getServiceName(), serviceId,
"127.0.0.1", registerConfig.getLocalServicePort()
);
String remoteAddress;
String[] remote;
int retry = 0;
do {
// 先睡个0.5秒等待连接成功再获取状态读端口
ThreadUtil.sleep(500);
JsonNode proxy = frpcClientClient.getProxyStatus(registerConfig.getServiceName(), serviceId);
remoteAddress = proxy.path("remote_addr")
.asText("127.0.0.1:" + registerConfig.getLocalServicePort());
remote = remoteAddress.split(":");
retry++;
} while (retry < 3 && remote.length < 2);
if (retry == 3) {
throw new Exception("获取frp隧道信息重试次数过多,请手动添加隧道和注册中心");
}
this.consulClient.register(remoteAddress, Integer.parseInt(remote[1]));
this.registered = true;
}
}

@ -0,0 +1,63 @@
package cn.wustlinghang.wusthelper.internal.rpc.client;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.mywust.network.request.RequestFactory;
import cn.wustlinghang.wusthelper.internal.rpc.config.RegisterConfig;
import cn.wustlinghang.wusthelper.internal.rpc.entity.RegisterRequestBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
public class ConsulClient {
private final String serviceId;
private final String serviceName;
private final String consulAddress;
private final ObjectMapper objectMapper;
private final Requester requester;
public ConsulClient(String serviceId, RegisterConfig registerConfig, ObjectMapper objectMapper, Requester requester) {
this.serviceId = serviceId;
this.serviceName = registerConfig.getServiceName();
this.consulAddress = registerConfig.getConsulAddress();
this.objectMapper = objectMapper;
this.requester = requester;
}
public void register(String remoteAddress, int remotePort,
RegisterRequestBody.HealthCheckOption... healthCheckOption
) throws IOException {
var registerRequestBody = RegisterRequestBody.builder()
.id(serviceId)
.name(serviceName)
.address(remoteAddress)
.port(remotePort)
.checks(Lists.newArrayList(healthCheckOption))
.build();
byte[] registerRequestData = objectMapper.writeValueAsBytes(registerRequestBody);
var url = consulAddress + "/v1/agent/service/register";
var registerRequest = RequestFactory.makeHttpRequest(url, registerRequestData);
var registerResponse = requester.put(registerRequest);
if (registerResponse.getStatusCode() != HttpResponse.HTTP_OK) {
log.warn("注册中心注册不成功,请手动注册");
}
}
public void deregister() throws IOException {
var url = String.format("%s/v1/agent/service/deregister/%s", consulAddress, serviceId);
var deregisterRequest = RequestFactory.makeHttpRequest(url);
var deregisterResponse = requester.put(deregisterRequest);
if (deregisterResponse.getStatusCode() != HttpResponse.HTTP_OK) {
log.warn("服务注销不成功,请手动注册");
}
}
}

@ -0,0 +1,96 @@
package cn.wustlinghang.wusthelper.internal.rpc.client;
import cn.hutool.core.codec.Base64;
import cn.wustlinghang.mywust.network.request.RequestFactory;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.rpc.config.FrpConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;
import org.ini4j.Ini;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class FrpcClient {
private final String frpcAdminAddress;
private final String frpAuthHeaderValue;
private final Requester requester;
private final ObjectMapper objectMapper;
public FrpcClient(FrpConfig config, Requester requester, ObjectMapper objectMapper) {
this.frpcAdminAddress = config.getFrpcAdminAddress();
this.requester = requester;
this.objectMapper = objectMapper;
String username = config.getFrpcAdminUsername();
String password = config.getFrpcAdminPassword();
this.frpAuthHeaderValue = "Basic " + Base64.encode(username + ":" + password);
}
private String frpProxyName;
public void addFrpProxy(String serviceName, String serviceId, String localAddress, String localPort)
throws IOException {
this.frpProxyName = String.format("%s-%s", serviceName, serviceId);
Ini ini = this.getFrpConfig();
ini.put(frpProxyName, "type", "tcp");
ini.put(frpProxyName, "local_address", localAddress);
ini.put(frpProxyName, "local_port", localPort);
ini.put(frpProxyName, "use_compression", "true");
var output = new ByteArrayOutputStream();
ini.store(output);
this.reloadFrpConfig(ini);
}
public void removeProxy() throws IOException {
Ini ini = this.getFrpConfig();
ini.remove(this.frpProxyName);
this.reloadFrpConfig(ini);
}
public Ini getFrpConfig() throws IOException {
var frpConfigRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/config");
frpConfigRequest.addHeaders("Authorization", frpAuthHeaderValue);
var response = requester.get(frpConfigRequest);
return new Ini(new ByteArrayInputStream(response.getBody()));
}
public void reloadFrpConfig(Ini ini) throws IOException {
var output = new ByteArrayOutputStream();
ini.store(output);
var uploadRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/config", output.toByteArray());
uploadRequest.addHeaders("Authorization", frpAuthHeaderValue);
requester.put(uploadRequest);
var reloadRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/reload");
reloadRequest.addHeaders("Authorization", frpAuthHeaderValue);
requester.get(reloadRequest);
}
public JsonNode getProxyStatus(String serviceName, String serviceId) throws IOException {
var statusRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/status");
statusRequest.addHeaders("Authorization", frpAuthHeaderValue);
var statusResponse = requester.get(statusRequest);
JsonNode proxies = objectMapper.readTree(statusResponse.getBody()).path("tcp");
for (JsonNode proxy : proxies) {
if (proxy.path("name").asText().equals(serviceName + "-" + serviceId)) {
return proxy;
}
}
return MissingNode.getInstance();
}
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.rpc.config;
import lombok.Data;
@Data
public class FrpConfig {
private String frpcAdminAddress;
private String frpcAdminUsername;
private String frpcAdminPassword;
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.rpc.config;
import lombok.Data;
@Data
public class RegisterConfig {
private String localServicePort;
private String serviceName;
private String consulAddress;
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.rpc.entity;
import lombok.Builder;
import java.util.List;
@Builder
public record RegisterRequestBody(String address, int port, List<HealthCheckOption> checks, String name, String id) {
@Builder
public record HealthCheckOption(String http, String interval, String timeout) {
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1;
import cn.wustlinghang.wusthelper.internal.graduate.services.LoginService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.wusthelper.internal.graduate.services.CourseTableService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.graduate.services.ScoreService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.wusthelper.internal.graduate.services.StudentInfoService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1;
import cn.wustlinghang.wusthelper.internal.graduate.services.TrainingPlanService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -12,7 +12,7 @@ public abstract class BaseExceptionHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
public Response toResponse(RpcCommonResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
@ -29,7 +29,7 @@ public abstract class BaseExceptionHandler {
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -13,7 +13,7 @@ public class DefaultExceptionHandler extends BaseExceptionHandler implements Exc
public Response toResponse(Exception e) {
log.error("未知异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"DefaultExceptionHandler"
);

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -15,7 +15,7 @@ public class IOExceptionHandler extends BaseExceptionHandler implements Exceptio
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -14,7 +14,7 @@ public class ParseExceptionHandler extends BaseExceptionHandler implements Excep
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
@ -14,7 +14,7 @@ public class ValidationExceptionHandler extends BaseExceptionHandler
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
RpcCommonResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.GraduateRpcException;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.interceptor;
package cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.graduate.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.wusthelper.internal.library.services.BookCoverImageUrlService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.parsed.BookDetail;
import cn.wustlinghang.wusthelper.internal.library.services.BookDetailService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import cn.wustlinghang.wusthelper.internal.library.services.BookHoldingService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.wusthelper.internal.library.services.LoginService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -12,7 +12,7 @@ public abstract class BaseExceptionHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
public Response toResponse(RpcCommonResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
@ -29,7 +29,7 @@ public abstract class BaseExceptionHandler {
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -13,7 +13,7 @@ public class DefaultExceptionHandler extends BaseExceptionHandler implements Exc
public Response toResponse(Exception e) {
log.error("未知异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"DefaultExceptionHandler"
);

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -15,7 +15,7 @@ public class IOExceptionHandler extends BaseExceptionHandler implements Exceptio
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -14,7 +14,7 @@ public class ParseExceptionHandler extends BaseExceptionHandler implements Excep
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
@ -14,7 +14,7 @@ public class ValidationExceptionHandler extends BaseExceptionHandler
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
RpcCommonResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.LibraryRpcException;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.interceptor;
package cn.wustlinghang.wusthelper.internal.library.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.physics.api.http.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.library.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1;
import cn.wustlinghang.wusthelper.internal.physics.services.LoginService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1;
import cn.wustlinghang.mywust.data.physics.PhysicsCourse;
import cn.wustlinghang.wusthelper.internal.physics.services.CourseTableService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.physics.services.ScoreService;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -12,7 +12,7 @@ public abstract class BaseExceptionHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
public Response toResponse(RpcCommonResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
@ -29,7 +29,7 @@ public abstract class BaseExceptionHandler {
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -13,7 +13,7 @@ public class DefaultExceptionHandler extends BaseExceptionHandler implements Exc
public Response toResponse(Exception e) {
log.error("未知异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"DefaultExceptionHandler"
);

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -15,7 +15,7 @@ public class IOExceptionHandler extends BaseExceptionHandler implements Exceptio
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -14,7 +14,7 @@ public class ParseExceptionHandler extends BaseExceptionHandler implements Excep
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
@ -14,7 +14,7 @@ public class ValidationExceptionHandler extends BaseExceptionHandler
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
RpcCommonResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.http.handler;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.PhysicsRpcException;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.interceptor;
package cn.wustlinghang.wusthelper.internal.physics.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.graduate.api.http.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.physics.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;

@ -30,16 +30,22 @@
<version>3.1.3.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.mywust</groupId>
<artifactId>mywust-core</artifactId>
<version>0.0.2-SNAPSHOT</version>
<version>0.0.2-beta</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.mywust</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>0.0.2-SNAPSHOT</version>
<version>0.0.2-beta</version>
<scope>compile</scope>
</dependency>
<dependency>

@ -29,6 +29,7 @@
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>

@ -1,16 +0,0 @@
package cn.wustlinghang.wusthelper.internal.undergrad;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Startup
@Singleton
public class Main {
@PostConstruct
public void run() {
log.info("Undergrad service started.");
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.wusthelper.internal.undergrad.services.LoginService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.wusthelper.internal.undergrad.services.CourseTableService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.wusthelper.internal.undergrad.services.CreditStatusService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradExamDelayApiService;
import cn.wustlinghang.mywust.data.global.Score;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ExamDelayApplicationService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ScoreService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.wusthelper.internal.undergrad.services.StudentInfoService;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1;
import cn.wustlinghang.wusthelper.internal.undergrad.services.TrainingPlanService;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -12,7 +12,7 @@ public abstract class BaseExceptionHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
public Response toResponse(RpcCommonResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
@ -29,7 +29,7 @@ public abstract class BaseExceptionHandler {
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
response = RpcResponse.error(RpcCommonResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(status)

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -13,7 +13,7 @@ public class DefaultExceptionHandler extends BaseExceptionHandler implements Exc
public Response toResponse(Exception e) {
log.error("未知异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"DefaultExceptionHandler"
);

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -15,7 +15,7 @@ public class IOExceptionHandler extends BaseExceptionHandler implements Exceptio
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@ -14,7 +14,7 @@ public class ParseExceptionHandler extends BaseExceptionHandler implements Excep
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
RpcCommonResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcCommonResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
@ -14,7 +14,7 @@ public class ValidationExceptionHandler extends BaseExceptionHandler
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
RpcCommonResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler;
import cn.wustlinghang.wusthelper.internal.rpc.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.internal.rpc.exception.RpcException;

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.http.interceptor;
package cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.interceptor;
import cn.wustlinghang.wusthelper.internal.library.api.http.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.undergrad.api.http.v1.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.internal.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;

@ -0,0 +1,107 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.undergrad.rpc.client.ConsulClient;
import cn.wustlinghang.wusthelper.internal.undergrad.rpc.client.FrpcClient;
import cn.wustlinghang.wusthelper.internal.undergrad.rpc.config.RpcConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Slf4j
@Startup
@ApplicationScoped
public class FrpConsulRegister {
@ConfigProperty(name = "quarkus.http.port")
String localServicePort;
private final String serviceId;
private final RpcConfig rpcConfig;
private final FrpcClient frpcClientClient;
private final ConsulClient consulClient;
private boolean registered = false;
public FrpConsulRegister(RpcConfig rpcConfig, FrpcClient frpcClientClient, Requester requester,
ObjectMapper objectMapper) {
this.rpcConfig = rpcConfig;
this.frpcClientClient = frpcClientClient;
this.serviceId = RandomUtil.randomString(8);
this.consulClient = new ConsulClient(
rpcConfig.getServiceName(), this.serviceId,
rpcConfig.getConsulAddress(),
objectMapper, requester);
}
@PostConstruct
public void onStartup() {
ThreadUtil.execute(() -> {
try {
log.info("连接frp并注册consul...");
this.doRegister();
log.info("注册完毕");
} catch (Exception e) {
log.warn("注册服务时发生异常:", e);
log.warn("不进行转发注册,直接服务");
}
});
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown, "ShutdownHookThread"));
}
@PreDestroy
public void onShutdown() {
try {
if (this.registered) {
log.info("注销服务...");
this.consulClient.deregister();
this.frpcClientClient.removeProxy();
log.info("服务注销完毕");
this.registered = false;
}
} catch (Exception e) {
log.warn("注销服务时发生异常:", e);
}
}
private void doRegister() throws Exception {
frpcClientClient.addFrpProxy(
rpcConfig.getServiceName(), serviceId,
"127.0.0.1", localServicePort
);
String remoteAddress;
String[] remote;
int retry = 0;
do {
// 先睡个0.5秒等待连接成功再获取状态读端口
ThreadUtil.sleep(500);
JsonNode proxy = frpcClientClient.getProxyStatus(rpcConfig.getServiceName(), serviceId);
remoteAddress = proxy.path("remote_addr")
.asText("127.0.0.1:" + localServicePort);
remote = remoteAddress.split(":");
retry++;
} while (retry < 3 && remote.length < 2);
if (retry == 3) {
throw new Exception("获取frp隧道信息重试次数过多,请手动添加隧道和注册中心");
}
this.consulClient.register(remoteAddress, Integer.parseInt(remote[1]));
this.registered = true;
}
}

@ -0,0 +1,60 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.client;
import cn.wustlinghang.mywust.network.request.RequestFactory;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.wusthelper.internal.undergrad.rpc.entity.RegisterRequestBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
public class ConsulClient {
private final String serviceId;
private final String serviceName;
private final String consulAddress;
private final ObjectMapper objectMapper;
private final Requester requester;
public ConsulClient(String serviceName, String serviceId, String consulAddress,
ObjectMapper objectMapper, Requester requester) {
this.serviceId = serviceId;
this.serviceName = serviceName;
this.consulAddress = consulAddress;
this.objectMapper = objectMapper;
this.requester = requester;
}
public void register(String remoteAddress, int remotePort) throws IOException {
var checksItem = RegisterRequestBody.ChecksItem.builder()
.http("http://" + remoteAddress + "/health")
.interval("3s")
.build();
var registerRequestBody = RegisterRequestBody.builder()
.id(serviceId)
.name(serviceName)
.address("127.0.0.1")
.port(remotePort)
.checks(Lists.newArrayList(checksItem))
.build();
byte[] registerRequestData = objectMapper.writeValueAsBytes(registerRequestBody);
var registerRequest = RequestFactory.makeHttpRequest(consulAddress + "/v1/agent/service/register", registerRequestData);
var registerResponse = requester.put(registerRequest);
if (registerResponse.getStatusCode() != HttpResponse.HTTP_OK) {
log.warn("注册中心注册不成功,请手动注册");
}
}
public void deregister() throws IOException {
var deregisterRequest = RequestFactory.makeHttpRequest(consulAddress + "/v1/agent/service/deregister/" + serviceId);
var deregisterResponse = requester.put(deregisterRequest);
if (deregisterResponse.getStatusCode() != HttpResponse.HTTP_OK) {
log.warn("服务注销不成功,请手动注册");
}
}
}

@ -0,0 +1,100 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.client;
import cn.hutool.core.codec.Base64;
import cn.wustlinghang.mywust.network.request.RequestFactory;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.wusthelper.internal.undergrad.rpc.config.FrpConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;
import jakarta.inject.Singleton;
import org.ini4j.Ini;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@Singleton
public class FrpcClient {
private final String frpcAdminAddress;
private final String frpAuthHeaderValue;
private final Requester requester;
private final ObjectMapper objectMapper;
private String frpProxyName;
public FrpcClient(FrpConfig frpConfig,
Requester requester, ObjectMapper objectMapper) {
this.frpcAdminAddress = frpConfig.getFrpcAdminAddress();
this.requester = requester;
this.objectMapper = objectMapper;
String username = frpConfig.getFrpcAdminUsername();
String password = frpConfig.getFrpcAdminPassword();
this.frpAuthHeaderValue = "Basic " + Base64.encode(username + ":" + password);
}
public void addFrpProxy(String serviceName, String serviceId, String localAddress, String localPort)
throws IOException {
this.frpProxyName = String.format("%s-%s", serviceName, serviceId);
Ini ini = this.getFrpConfig();
ini.put(frpProxyName, "type", "tcp");
ini.put(frpProxyName, "local_address", localAddress);
ini.put(frpProxyName, "local_port", localPort);
ini.put(frpProxyName, "use_compression", "true");
var output = new ByteArrayOutputStream();
ini.store(output);
this.reloadFrpConfig(ini);
}
public void removeProxy() throws IOException {
Ini ini = this.getFrpConfig();
ini.remove(this.frpProxyName);
this.reloadFrpConfig(ini);
}
public Ini getFrpConfig() throws IOException {
var frpConfigRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/config");
frpConfigRequest.addHeaders("Authorization", frpAuthHeaderValue);
var response = requester.get(frpConfigRequest);
return new Ini(new ByteArrayInputStream(response.getBody()));
}
public void reloadFrpConfig(Ini ini) throws IOException {
var output = new ByteArrayOutputStream();
ini.store(output);
var uploadRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/config", output.toByteArray());
uploadRequest.addHeaders("Authorization", frpAuthHeaderValue);
requester.put(uploadRequest);
var reloadRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/reload");
reloadRequest.addHeaders("Authorization", frpAuthHeaderValue);
requester.get(reloadRequest);
}
public JsonNode getProxyStatus(String serviceName, String serviceId) throws IOException {
var statusRequest = RequestFactory.makeHttpRequest(frpcAdminAddress + "/api/status");
statusRequest.addHeaders("Authorization", frpAuthHeaderValue);
var statusResponse = requester.get(statusRequest);
JsonNode proxies = objectMapper.readTree(statusResponse.getBody()).path("tcp");
for (JsonNode proxy : proxies) {
if (proxy.path("name").asText().equals(serviceName + "-" + serviceId)) {
return proxy;
}
}
return MissingNode.getInstance();
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.config;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import lombok.Data;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class FrpConfig {
@DefaultValue("http://127.0.0.1:7400")
@ConfigProperty(name = "frpc.admin-api.address")
String frpcAdminAddress;
@DefaultValue("")
@ConfigProperty(name = "frpc.admin.username")
String frpcAdminUsername;
@DefaultValue("")
@ConfigProperty(name = "frpc.admin.password")
String frpcAdminPassword;
}

@ -0,0 +1,18 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.config;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import lombok.Data;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Data
@Singleton
public class RpcConfig {
@DefaultValue("default.service")
@ConfigProperty(name = "rpc.service.name")
String serviceName;
@DefaultValue("http://127.0.0.1:8500")
@ConfigProperty(name = "rpc.register.consul-api.address")
String consulAddress;
}

@ -0,0 +1,13 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.entity;
import lombok.Builder;
import java.util.List;
@Builder
public record RegisterRequestBody(String address, int port, List<ChecksItem> checks, String name, String id) {
@Builder
public record ChecksItem(String http, String interval) {
}
}

@ -0,0 +1,14 @@
package cn.wustlinghang.wusthelper.internal.undergrad.rpc.health;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("/health")
public class HealthCheck {
private static final Response successResponse = Response.accepted().status(200).build();
@GET
@Path("/")
public Response response() {return successResponse;}
}

@ -1,4 +1,6 @@
quarkus.http.port=22800
quarkus.http.enable-compression=true
#quarkus.log.level=DEBUG
quarkus.log.file.encoding=UTF-8
@ -9,3 +11,10 @@ quarkus.package.type=uber-jar
# 但也只是能编译完成,目前的编译产物完全不可用,有非常多的严重bug
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args=--initialize-at-run-time=cn.wustlinghang.mywust,--initialize-at-run-time=cn.wustlinghang.wusthelper,--enable-url-protocols=https
rpc.service.name=wusthelper.undergrad
rpc.register.consul-api.address=http://127.0.0.1:8500
frpc.admin-api.address=http://127.0.0.1:7400
frpc.admin.username=admin
frpc.admin.password=admin
Loading…
Cancel
Save