From 7050b438f9c8a5c1d84c72269e4bddec63c33fc0 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 2 Apr 2024 16:56:57 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E8=8E=B7=E5=8F=96=20cron=20?= =?UTF-8?q?=E4=B8=8B=E6=AC=A1=E6=89=A7=E8=A1=8C=E6=97=B6=E9=97=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/handler/GlobalExceptionHandler.java | 1 + .../controller/ExpressionController.http | 11 ++++ .../controller/ExpressionController.java | 59 +++++++++++++++++++ .../request/exoression/CronNextRequest.java | 37 ++++++++++++ .../module/infra/entity/vo/CronNextVO.java | 34 +++++++++++ 5 files changed, 142 insertions(+) create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.http create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/exoression/CronNextRequest.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/CronNextVO.java diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java index 2fff803a..33d79d06 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java @@ -243,6 +243,7 @@ public class GlobalExceptionHandler { return ErrorCode.INTERNAL_SERVER_ERROR.wrapper(); } + // TODO kit @ExceptionHandler(value = ParseCronException.class) public HttpWrapper parseCronExceptionHandler(ParseCronException ex) { log.error("parseCronExceptionHandler", ex); diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.http b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.http new file mode 100644 index 00000000..36601d1c --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.http @@ -0,0 +1,11 @@ +### 获取 cron 下次执行时间 +POST {{baseUrl}}/infra/expression/cron-next +Content-Type: application/json + +{ + "expression": "5 */3 * * * ?", + "times": 2 +} + + +### \ No newline at end of file diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.java new file mode 100644 index 00000000..947d3820 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/ExpressionController.java @@ -0,0 +1,59 @@ +package com.orion.ops.module.infra.controller; + +import com.orion.lang.utils.collect.Lists; +import com.orion.lang.utils.time.Dates; +import com.orion.lang.utils.time.cron.Cron; +import com.orion.lang.utils.time.cron.CronSupport; +import com.orion.ops.framework.web.core.annotation.RestWrapper; +import com.orion.ops.module.infra.entity.request.exoression.CronNextRequest; +import com.orion.ops.module.infra.entity.vo.CronNextVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.security.PermitAll; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 表达式服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/4/2 16:33 + */ +@Tag(name = "infra - 表达式服务") +@Slf4j +@Validated +@RestWrapper +@RestController +@RequestMapping("/infra/expression") +@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"}) +public class ExpressionController { + + @PermitAll + @PostMapping("/cron-next") + @Operation(summary = "获取 cron 下次执行时间") + public CronNextVO getCronNextTime(@Validated @RequestBody CronNextRequest request) { + CronNextVO next = new CronNextVO(); + try { + Cron cron = Cron.of(request.getExpression()); + List nextTime = CronSupport.getNextTime(cron, request.getTimes()) + .stream() + .map(Dates::format) + .collect(Collectors.toList()); + next.setNext(nextTime); + next.setValid(true); + } catch (Exception e) { + next.setNext(Lists.empty()); + next.setValid(false); + } + return next; + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/exoression/CronNextRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/exoression/CronNextRequest.java new file mode 100644 index 00000000..81d4e066 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/exoression/CronNextRequest.java @@ -0,0 +1,37 @@ +package com.orion.ops.module.infra.entity.request.exoression; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * cron 下次执行时间请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/4/2 16:42 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "CronNextRequest", description = "cron 下次执行时间请求对象") +public class CronNextRequest implements Serializable { + + @NotBlank + @Schema(description = "cron 表达式") + private String expression; + + @NotNull + @Range(min = 1, max = 100) + @Schema(description = "次数") + private Integer times; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/CronNextVO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/CronNextVO.java new file mode 100644 index 00000000..bef32431 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/CronNextVO.java @@ -0,0 +1,34 @@ +package com.orion.ops.module.infra.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * cron 下次执行时间响应对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/4/2 16:35 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "CronNextVO", description = "cron 下次执行时间响应对象") +public class CronNextVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "表达式是否正确") + private Boolean valid; + + @Schema(description = "下次执行时间") + private List next; + +}