diff --git a/pom.xml b/pom.xml
index f7d4a06..558441a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.5
+ 2.7.17
com.cmhi
@@ -14,7 +14,7 @@
game_database_service
game_database_service
- 21
+ 1.8
@@ -64,7 +64,7 @@
org.mybatis
mybatis-spring
- 3.0.2
+ 2.1.1
javax.servlet
@@ -130,13 +130,18 @@
org.mybatis.spring.boot
mybatis-spring-boot-starter
- 3.0.2
+ 2.3.1
org.yaml
snakeyaml
2.1
+
+ io.projectreactor
+ reactor-core
+ 3.4.16
+
diff --git a/src/main/java/com/cmhi/gds/common/ErrorCode.java b/src/main/java/com/cmhi/gds/common/ErrorCode.java
index 80e3b9e..fcb1417 100644
--- a/src/main/java/com/cmhi/gds/common/ErrorCode.java
+++ b/src/main/java/com/cmhi/gds/common/ErrorCode.java
@@ -334,16 +334,31 @@ public enum ErrorCode implements BaseEnum {
* @return the http code
*/
public int getHttpCode() {
- return switch (this) {
- case ERR_OK -> HttpServletResponse.SC_OK;
- case ERR_SYSTEMEXCEPTION, ERR_PARAMEXCEPTION -> HttpServletResponse.SC_EXPECTATION_FAILED;
- case ERR_TOKENTIMEOUT, ERR_REQTIMEOUT -> HttpServletResponse.SC_REQUEST_TIMEOUT;
- case ERR_UNTRUSTTOKEN, ERR_UNTRUSTHOST, ERR_LOGOUT -> HttpServletResponse.SC_UNAUTHORIZED;
- case ERR_MISSAUTHHEAD, ERR_PARAMS, ERR_INPUTFORMAT, ERR_INPUTMISS -> HttpServletResponse.SC_BAD_REQUEST;
- case ERR_UNSUPPORT -> HttpServletResponse.SC_METHOD_NOT_ALLOWED;
- case ERR_UNKNOWNINTERFACE -> HttpServletResponse.SC_NOT_FOUND;
- default -> HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
- };
+ switch (this) {
+ case ERR_OK:
+ return HttpServletResponse.SC_OK;
+ case ERR_SYSTEMEXCEPTION:
+ case ERR_PARAMEXCEPTION:
+ return HttpServletResponse.SC_EXPECTATION_FAILED;
+ case ERR_TOKENTIMEOUT:
+ case ERR_REQTIMEOUT:
+ return HttpServletResponse.SC_REQUEST_TIMEOUT;
+ case ERR_UNTRUSTTOKEN:
+ case ERR_UNTRUSTHOST:
+ case ERR_LOGOUT:
+ return HttpServletResponse.SC_UNAUTHORIZED;
+ case ERR_MISSAUTHHEAD:
+ case ERR_PARAMS:
+ case ERR_INPUTFORMAT:
+ case ERR_INPUTMISS:
+ return HttpServletResponse.SC_BAD_REQUEST;
+ case ERR_UNSUPPORT:
+ return HttpServletResponse.SC_METHOD_NOT_ALLOWED;
+ case ERR_UNKNOWNINTERFACE:
+ return HttpServletResponse.SC_NOT_FOUND;
+ default:
+ return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+ }
}
/**
diff --git a/src/main/java/com/cmhi/gds/common/GlobalConfigure.java b/src/main/java/com/cmhi/gds/common/GlobalConfigure.java
new file mode 100644
index 0000000..2f3a4ec
--- /dev/null
+++ b/src/main/java/com/cmhi/gds/common/GlobalConfigure.java
@@ -0,0 +1,11 @@
+package com.cmhi.gds.common;
+
+public class GlobalConfigure {
+ private GlobalConfigure() {
+ throw new AssertionError("Instantiating utility class.");
+ }
+
+ public static volatile boolean CHECK_PROTO_REQUEST_TIMEOUT = false;
+
+ public static volatile long REQUEST_TIMEOUT_MS = 5 * 1000;
+}
diff --git a/src/main/java/com/cmhi/gds/controller/GameDatabaseInfoController.java b/src/main/java/com/cmhi/gds/controller/GameDatabaseInfoController.java
index 1b76714..076c5f1 100644
--- a/src/main/java/com/cmhi/gds/controller/GameDatabaseInfoController.java
+++ b/src/main/java/com/cmhi/gds/controller/GameDatabaseInfoController.java
@@ -3,16 +3,20 @@ package com.cmhi.gds.controller;
import com.cmhi.gds.common.ErrorCode;
import com.cmhi.gds.pojo.dto.protocol.base.ProtocolReqDTO;
import com.cmhi.gds.pojo.dto.protocol.base.ProtocolRespDTO;
+import com.cmhi.gds.pojo.dto.protocol.info.GameInfoContent;
+import com.cmhi.gds.pojo.dto.protocol.info.GameInfoDetail;
import com.cmhi.gds.pojo.dto.protocol.info.GameListSummary;
-import com.cmhi.gds.pojo.dto.protocol.info.GameServerReq;
import com.cmhi.gds.pojo.dto.protocol.info.GameServerRsp;
+import com.cmhi.gds.pojo.dto.protocol.info.GetGameInfoDetailReq;
+import com.cmhi.gds.pojo.dto.protocol.info.GetGamesInfoRsp;
import com.cmhi.gds.pojo.dto.protocol.info.GetGamesSummaryRsp;
-import com.cmhi.gds.pojo.vo.GameTableItems;
+import com.cmhi.gds.pojo.dto.protocol.info.ReportGameServerReq;
+import com.cmhi.gds.pojo.vo.GameTableItemsDetail;
+import com.cmhi.gds.pojo.vo.GameTableItemsSummary;
import com.cmhi.gds.security.annotation.Decryption;
import com.cmhi.gds.security.annotation.Encryption;
import com.cmhi.gds.service.GameDatabaseServiceService;
import com.cmhi.gds.validation.group.ValidGroups;
-import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@@ -23,8 +27,12 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
+import javax.annotation.Resource;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
@Controller
@RequestMapping(value = "/gameinfo")
@@ -40,17 +48,16 @@ public class GameDatabaseInfoController {
@GetMapping("gamelistsummary")
@ResponseBody
-
public ProtocolRespDTO getGameListSummary() {
GetGamesSummaryRsp rspInfo = GetGamesSummaryRsp.builder()
.items(new ArrayList<>())
.build();
- List gameList = gameDatabaseServiceService.getGameTableSummaryItems();
+ List gameList = gameDatabaseServiceService.getGameTableSummaryItems();
if (!gameList.isEmpty()) {
- for (GameTableItems v : gameList) {
+ for (GameTableItemsSummary v : gameList) {
GameListSummary item = GameListSummary.builder()
.gameId(v.getGameId())
.build();
@@ -74,11 +81,69 @@ public class GameDatabaseInfoController {
return ProtocolRespDTO.result(ErrorCode.ERR_OK, rspInfo);
}
+ @PostMapping("gamelistDetails")
+ @ResponseBody
+ public ProtocolRespDTO getGameInfoDetails(@Validated(ValidGroups.AddGameServiceValid.class)
+ @RequestBody ProtocolReqDTO mr) {
+ GetGamesInfoRsp rspInfo = GetGamesInfoRsp.builder().build();
+ List gameContent = new ArrayList<>();
+
+ //获取TaskId列表
+ List reqTaskIds = Optional.ofNullable(mr.getMsgContent().getItems())
+ .orElse(new ArrayList<>());
+
+ List ret = gameDatabaseServiceService.getGameTableItems(reqTaskIds);
+
+ // 不存在的ID
+ reqTaskIds.stream()
+ .filter(v -> ret.stream().noneMatch(k -> k.getGameId().equals(v)))
+ .forEach(v -> {
+ GameInfoContent gi = GameInfoContent.builder().build();
+ gi.setGameId(v);
+ gi.setStatus(ErrorCode.ERR_NOSUCHTASK.getCode());
+ gi.setMessage(new String[]{ErrorCode.ERR_NOSUCHTASK.getMsg()});
+ gameContent.add(gi);
+ });
+
+ for (GameTableItemsDetail v : ret) {
+ GameInfoContent gi = GameInfoContent.builder()
+ .gameId(v.getGameId())
+ .company(v.getCompany())
+ .name(v.getName())
+ .gamesInfo(new ArrayList<>())
+ .build();
+
+ gi.setStatus(ErrorCode.ERR_OK.getCode());
+ gi.setMessage(new String[]{ErrorCode.ERR_OK.getMsg()});
+
+ v.getGameDetails().forEach(k -> {
+ GameInfoDetail gd = GameInfoDetail.builder()
+ .gameInfoId(k.getGameInfoId())
+ .version(k.getVersion())
+ .gameFileName(k.getFilename())
+ .md5sum(k.getMd5sum())
+ .build();
+
+ gi.getGamesInfo().add(gd);
+ });
+
+ gameContent.add(gi);
+ }
+
+ rspInfo.getItems().addAll(gameContent.stream().sorted(Comparator.comparingLong(GameInfoContent::getGameId))
+ .collect(Collectors.toList()));
+
+ rspInfo.setStatus(ErrorCode.ERR_OK.getCode());
+ rspInfo.setMessage(new String[]{ErrorCode.ERR_OK.getMsg()});
+
+ return ProtocolRespDTO.result(ErrorCode.ERR_OK, rspInfo);
+ }
+
@PostMapping("/gamedata")
@ResponseBody
public ProtocolRespDTO reportGameServiceData(
@Validated(ValidGroups.AddGameServiceValid.class)
- @RequestBody ProtocolReqDTO mr) {
+ @RequestBody ProtocolReqDTO mr) {
GameServerRsp rspInfo = new GameServerRsp();
rspInfo.setItems(new ArrayList<>());
//
diff --git a/src/main/java/com/cmhi/gds/exception/GlobalExceptionHandler.java b/src/main/java/com/cmhi/gds/exception/GlobalExceptionHandler.java
index 2669cf9..58098ba 100644
--- a/src/main/java/com/cmhi/gds/exception/GlobalExceptionHandler.java
+++ b/src/main/java/com/cmhi/gds/exception/GlobalExceptionHandler.java
@@ -44,7 +44,6 @@ public class GlobalExceptionHandler {
String reqPath = req.getRequestURI();
String reqIp = req.getRemoteAddr();
String reqToken = req.getHeader("Authorization");
-
if (reqToken != null && !reqToken.isEmpty()) {
reqToken = reqToken.replace(ConstValue.STRING_HTTP_AUTH_HEAD, "");
}
@@ -66,10 +65,9 @@ public class GlobalExceptionHandler {
}
sb.append("]");
- log.error("""
- Interface [{}] request <{}> from {}, token = <{}>
- +++ Request: {}
- --- Verify params failed: {}""",
+ log.error("Interface [{}] request <{}> from {}, token = <{}>\n" +
+ "+++ Request: {}\n" +
+ "--- Verify params failed: {}",
reqType, reqPath, reqIp, reqToken, Helper.inputStream2String(req.getInputStream()), sb);
} catch (Exception ignored) {
}
@@ -109,14 +107,12 @@ public class GlobalExceptionHandler {
String reqPath = req.getRequestURI();
String reqIp = req.getRemoteAddr();
String reqToken = req.getHeader("Authorization");
-
if (reqToken != null && !reqToken.isEmpty()) {
reqToken = reqToken.replace(ConstValue.STRING_HTTP_AUTH_HEAD, "");
}
- log.error("""
- Interface [{}] request <{}> from {}, token = <{}>
- +++ Request: {}
- --- Verify params failed: {}""",
+ log.error("Interface [{}] request <{}> from {}, token = <{}>\n" +
+ "+++ Request: {}\n" +
+ "--- Verify params failed: {}",
reqType, reqPath, reqIp, reqToken, Helper.inputStream2String(req.getInputStream()),
ex.getMessage() == null ? ex.getDescription() : ex.getMessage());
} catch (Exception ignored) {
@@ -163,10 +159,9 @@ public class GlobalExceptionHandler {
if (reqToken != null && !reqToken.isEmpty()) {
reqToken = reqToken.replace(ConstValue.STRING_HTTP_AUTH_HEAD, "");
}
- log.error("""
- Interface [{}] request <{}> from {}, token = <{}>
- +++ Request: {}
- --- Verify params failed: {}""",
+ log.error("Interface [{}] request <{}> from {}, token = <{}>\n" +
+ "+++ Request: {}\n" +
+ "--- Verify params failed: {}",
reqType, reqPath, reqIp, reqToken, Helper.inputStream2String(req.getInputStream()),
ex.getMessage());
} catch (Exception ignored) {
diff --git a/src/main/java/com/cmhi/gds/interceptor/RequestBodyCacheWrapper.java b/src/main/java/com/cmhi/gds/interceptor/RequestBodyCacheWrapper.java
new file mode 100644
index 0000000..4482b3f
--- /dev/null
+++ b/src/main/java/com/cmhi/gds/interceptor/RequestBodyCacheWrapper.java
@@ -0,0 +1,106 @@
+package com.cmhi.gds.interceptor;
+
+import com.cmhi.gds.misc.Helper;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+
+/**
+ * The type Request body cache wrapper.
+ *
+ * @author
+ */
+public class RequestBodyCacheWrapper extends HttpServletRequestWrapper {
+ /**
+ * The Body.
+ */
+ private final byte[] body;
+
+ /**
+ * Instantiates a new Request body cache wrapper.
+ *
+ * @param request the request
+ */
+ public RequestBodyCacheWrapper(HttpServletRequest request) {
+ super(request);
+ // 将body数据存储起来
+ String bodyStr = getBodyString(request);
+ body = bodyStr.getBytes(Charset.defaultCharset());
+ }
+
+ /**
+ * Gets body string.
+ *
+ * @param request the request
+ * @return the body string
+ */
+ public String getBodyString(final ServletRequest request) {
+ try {
+ return Helper.inputStream2String(request.getInputStream());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Gets body string.
+ *
+ * @return the body string
+ */
+ public String getBodyString() {
+ final InputStream inputStream = new ByteArrayInputStream(body);
+
+ return Helper.inputStream2String(inputStream);
+ }
+
+ /**
+ * Gets reader.
+ *
+ * @return the reader
+ */
+ @Override
+ public BufferedReader getReader() {
+ return new BufferedReader(new InputStreamReader(getInputStream()));
+ }
+
+ /**
+ * Gets input stream.
+ *
+ * @return the input stream
+ */
+ @Override
+ public ServletInputStream getInputStream() {
+
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
+
+ return new ServletInputStream() {
+ @Override
+ public int read() {
+ return inputStream.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return false;
+ }
+
+ @Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+ }
+ };
+ }
+}
diff --git a/src/main/java/com/cmhi/gds/interceptor/RequestBodyFilter.java b/src/main/java/com/cmhi/gds/interceptor/RequestBodyFilter.java
new file mode 100644
index 0000000..ea6c269
--- /dev/null
+++ b/src/main/java/com/cmhi/gds/interceptor/RequestBodyFilter.java
@@ -0,0 +1,52 @@
+package com.cmhi.gds.interceptor;
+
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * The type Request body filter.
+ *
+ * @author
+ */
+
+@WebFilter(filterName = "RequestBodyFilter", urlPatterns = "/*")
+public class RequestBodyFilter implements Filter {
+ /**
+ * Init.
+ *
+ * @param filterConfig the filter config
+ */
+ @Override
+ public void init(FilterConfig filterConfig) {
+ }
+
+ /**
+ * Destroy.
+ */
+ @Override
+ public void destroy() {
+ }
+
+ /**
+ * Do filter.
+ *
+ * @param request the request
+ * @param response the response
+ * @param filterChain the filter chain
+ * @throws IOException the io exception
+ * @throws ServletException the servlet exception
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+ ServletRequest requestWrapper = new RequestBodyCacheWrapper((HttpServletRequest) request);
+ filterChain.doFilter(requestWrapper, response);
+ }
+}
diff --git a/src/main/java/com/cmhi/gds/interceptor/RequestProtocolSecurity.java b/src/main/java/com/cmhi/gds/interceptor/RequestProtocolSecurity.java
new file mode 100644
index 0000000..6247ff1
--- /dev/null
+++ b/src/main/java/com/cmhi/gds/interceptor/RequestProtocolSecurity.java
@@ -0,0 +1,104 @@
+package com.cmhi.gds.interceptor;
+
+import com.cmhi.gds.security.annotation.Decryption;
+import com.cmhi.gds.service.ProtocolSecurityService;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * The type Request protocol security.
+ *
+ * @author
+ */
+@Slf4j
+@RestControllerAdvice
+public class RequestProtocolSecurity implements RequestBodyAdvice {
+
+ /**
+ * The Protocol security service.
+ */
+ @Resource
+ private ProtocolSecurityService protocolSecurityService;
+
+ /**
+ * Supports boolean.
+ *
+ * @param methodParameter the method parameter
+ * @param type the type
+ * @param aClass the a class
+ * @return the boolean
+ */
+ @Override
+ public boolean supports(@NotNull MethodParameter methodParameter,
+ @NotNull Type type,
+ @NotNull Class extends HttpMessageConverter>> aClass) {
+ return methodParameter.getContainingClass().isAnnotationPresent(Decryption.class)
+ || methodParameter.hasMethodAnnotation(Decryption.class);
+ }
+
+ /**
+ * Before body read http input message.
+ *
+ * @param httpInputMessage the http input message
+ * @param methodParameter the method parameter
+ * @param type the type
+ * @param aClass the a class
+ * @return the http input message
+ */
+ @Override
+ @NotNull
+ public HttpInputMessage beforeBodyRead(@NotNull HttpInputMessage httpInputMessage,
+ @NotNull MethodParameter methodParameter,
+ @NotNull Type type,
+ @NotNull Class extends HttpMessageConverter>> aClass) throws IOException {
+ return protocolSecurityService.decryptProtocol(httpInputMessage);
+ }
+
+ /**
+ * Handle empty body object.
+ *
+ * @param o the o
+ * @param httpInputMessage the http input message
+ * @param methodParameter the method parameter
+ * @param type the type
+ * @param aClass the a class
+ * @return the object
+ */
+ @Override
+ public Object handleEmptyBody(Object o,
+ @NotNull HttpInputMessage httpInputMessage,
+ @NotNull MethodParameter methodParameter,
+ @NotNull Type type,
+ @NotNull Class extends HttpMessageConverter>> aClass) {
+ return o;
+ }
+
+ /**
+ * After body read object.
+ *
+ * @param o the o
+ * @param httpInputMessage the http input message
+ * @param methodParameter the method parameter
+ * @param type the type
+ * @param aClass the a class
+ * @return the object
+ */
+ @Override
+ @NotNull
+ public Object afterBodyRead(@NotNull Object o,
+ @NotNull HttpInputMessage httpInputMessage,
+ @NotNull MethodParameter methodParameter,
+ @NotNull Type type,
+ @NotNull Class extends HttpMessageConverter>> aClass) {
+ return o;
+ }
+}
diff --git a/src/main/java/com/cmhi/gds/interceptor/ResponseProtocolSecurity.java b/src/main/java/com/cmhi/gds/interceptor/ResponseProtocolSecurity.java
new file mode 100644
index 0000000..1311e6a
--- /dev/null
+++ b/src/main/java/com/cmhi/gds/interceptor/ResponseProtocolSecurity.java
@@ -0,0 +1,83 @@
+package com.cmhi.gds.interceptor;
+
+import com.cmhi.gds.common.ProtoCryptoType;
+import com.cmhi.gds.common.SecurityConfigValue;
+import com.cmhi.gds.pojo.dto.protocol.base.ProtocolRespDTO;
+import com.cmhi.gds.security.annotation.Encryption;
+import com.cmhi.gds.service.ProtocolSecurityService;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import javax.annotation.Resource;
+
+/**
+ * The type Response protocol security.
+ *
+ * @author
+ */
+@Slf4j
+@RestControllerAdvice
+public class ResponseProtocolSecurity implements ResponseBodyAdvice