commit 143859e3eb8dd2ac9b0a90ec9fea33b8fd8097cd Author: lensfrex Date: Wed May 1 22:20:10 2024 +0800 init: 项目框架 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bac6f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +**/src/main/**/target/ +**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +.env + +.flattened-pom.xml + +*.log +*.gz diff --git a/README.md b/README.md new file mode 100644 index 0000000..2e131bf --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# rition + +云主机数据监测 \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..e69de29 diff --git a/docs/introduce.md b/docs/introduce.md new file mode 100644 index 0000000..9041152 --- /dev/null +++ b/docs/introduce.md @@ -0,0 +1,8 @@ +# Rition + +一个简单的云主机监测平台。 + +## 设计 + +整体结构设计: + diff --git a/rition-center/.gitignore b/rition-center/.gitignore new file mode 100644 index 0000000..8be8227 --- /dev/null +++ b/rition-center/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +**/src/main/**/target/ +**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/rition-center/api/pom.xml b/rition-center/api/pom.xml new file mode 100644 index 0000000..bd9217e --- /dev/null +++ b/rition-center/api/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + net.rition + rition-center + ${revision} + + + api + + + 17 + 17 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + net.rition + common + ${revision} + + + \ No newline at end of file diff --git a/rition-center/api/src/main/java/rition/backend/RitionBackendMain.java b/rition-center/api/src/main/java/rition/backend/RitionBackendMain.java new file mode 100644 index 0000000..9316aac --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/RitionBackendMain.java @@ -0,0 +1,15 @@ +package rition.backend; + +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 RitionBackendMain { + public static void main(String[] args) { + SpringApplication.run(RitionBackendMain.class); + } +} diff --git a/rition-center/api/src/main/java/rition/backend/annotation/RequireToken.java b/rition-center/api/src/main/java/rition/backend/annotation/RequireToken.java new file mode 100644 index 0000000..78690dc --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/annotation/RequireToken.java @@ -0,0 +1,15 @@ +package rition.backend.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 需要token + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface RequireToken { + boolean require() default true; +} diff --git a/rition-center/api/src/main/java/rition/backend/annotation/WithRequestIdResponse.java b/rition-center/api/src/main/java/rition/backend/annotation/WithRequestIdResponse.java new file mode 100644 index 0000000..cc605c9 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/annotation/WithRequestIdResponse.java @@ -0,0 +1,12 @@ +package rition.backend.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface WithRequestIdResponse { + boolean withRequestId() default true; +} diff --git a/rition-center/api/src/main/java/rition/backend/annotation/paramter/RequestId.java b/rition-center/api/src/main/java/rition/backend/annotation/paramter/RequestId.java new file mode 100644 index 0000000..9794677 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/annotation/paramter/RequestId.java @@ -0,0 +1,9 @@ +package rition.backend.annotation.paramter; + +import java.lang.annotation.*; + +@Documented +@Target({ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequestId { +} diff --git a/rition-center/api/src/main/java/rition/backend/annotation/paramter/Token.java b/rition-center/api/src/main/java/rition/backend/annotation/paramter/Token.java new file mode 100644 index 0000000..ae6a866 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/annotation/paramter/Token.java @@ -0,0 +1,4 @@ +package rition.backend.annotation.paramter; + +public @interface Token { +} diff --git a/rition-center/api/src/main/java/rition/backend/aop/advice/RequestIdResponseAdvice.java b/rition-center/api/src/main/java/rition/backend/aop/advice/RequestIdResponseAdvice.java new file mode 100644 index 0000000..de4fbf2 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/aop/advice/RequestIdResponseAdvice.java @@ -0,0 +1,61 @@ +package rition.backend.aop.advice; + +import jakarta.annotation.Nonnull; +import lombok.extern.slf4j.Slf4j; +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.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import rition.backend.annotation.WithRequestIdResponse; +import rition.backend.api.v1.dto.response.Response; +import rition.backend.api.v1.dto.response.ResponseWithRequestId; + +import java.util.Objects; + +/** + * 处理带有@WithRequestIdResponse注释的接口,在返回响应时,如果有RequestId,则将其放入响应的json中。 + * 一般来说,在执行该advice的时候,通常也意味着requestId已经被设置 + */ +@Slf4j +@ControllerAdvice +public class RequestIdResponseAdvice implements ResponseBodyAdvice { + @Override + public boolean supports(@Nonnull MethodParameter returnType, + @Nonnull Class> converterType) { + var targetMethod = Objects.requireNonNull(returnType.getMethod()); + + return targetMethod.getAnnotation(WithRequestIdResponse.class) != null || + targetMethod.getDeclaringClass().getAnnotation(WithRequestIdResponse.class) != null; + } + + @Override + public Object beforeBodyWrite(Object body, @Nonnull MethodParameter returnType, + @Nonnull MediaType selectedContentType, @Nonnull Class selectedConverterType, + @Nonnull ServerHttpRequest serverHttpRequest, + @Nonnull ServerHttpResponse serverHttpResponse) { + if (body == null) { + return null; + } + + if (body instanceof ResponseWithRequestId) { + return body; + } + + if (body instanceof Response response) { + var requestIdHeaderList = serverHttpResponse.getHeaders().get("X-Request-ID"); + + if (requestIdHeaderList == null || requestIdHeaderList.isEmpty()) { + return body; + } + + var responseWithResponseId = new ResponseWithRequestId<>(response); + responseWithResponseId.setRequestId(requestIdHeaderList.get(0)); + return responseWithResponseId; + } + + return body; + } +} diff --git a/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java b/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..95c0c6b --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java @@ -0,0 +1,137 @@ +package rition.backend.aop.exception; + +import com.fasterxml.jackson.databind.JsonMappingException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import org.springframework.web.servlet.NoHandlerFoundException; +import rition.backend.api.v1.dto.response.Response; +import rition.common.exception.ServiceException; +import rition.common.exception.code.ServiceCode; + +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + @ResponseBody + @ExceptionHandler(ServiceException.class) + public Response baseException(ServiceException e) { + return Response.error(e.getCodeValue(), e.getMessage()); + } + + @ResponseBody + @ExceptionHandler(Exception.class) + public Response baseException(Exception e) { + log.error("未处理的异常:", e); + return Response.error(ServiceCode.UnknownErr); + } + + /** + * 404 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(NoHandlerFoundException.class) + public Response baseException(NoHandlerFoundException e) { + return Response.error(ServiceCode.ApiNotImplement); + } + + /** + * 处理参数不完整的请求异常 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(MissingServletRequestParameterException.class) + public Response handler(MissingServletRequestParameterException e) { + log.debug("请求的参数不完整: " + e); + return Response.error(ServiceCode.ParamWrong); + } + + /** + * 处理参数不完整的请求异常 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(BindException.class) + public Response handler(BindException e) { + log.debug("请求的参数不完整: " + e); + return Response.error(ServiceCode.ParamWrong); + } + + /** + * 处理参数类型错误的请求异常(请求参数类型错误) + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public Response handler(MethodArgumentTypeMismatchException e) { + log.debug(String.format("请求错误(%s): %s", e.getClass().getName(), e)); + return Response.error(ServiceCode.ParamWrong); + } + + /** + * 处理参数类型错误的请求异常2(Json解析错误) + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(JsonMappingException.class) + public Response handler(JsonMappingException e) { + log.debug(String.format("请求错误(%s): %s", e.getClass().getName(), e)); + return Response.error(ServiceCode.ParamWrong); + } + + /** + * 处理参数类型错误的请求异常3(字段映射错误) + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(HttpMessageNotReadableException.class) + public Response handler(HttpMessageNotReadableException e) { + log.debug(String.format("请求错误(%s): %s", e.getClass().getName(), e)); + return Response.error(ServiceCode.ParamWrong); + } + + /** + * 处理请求头中“Content-Type”字段不正确的异常 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(HttpMediaTypeNotSupportedException.class) + public Response handler(HttpMediaTypeNotSupportedException e) { + log.debug(String.format("请求错误(%s): %s", e.getClass().getName(), e)); + return Response.error(ServiceCode.ParamWrong, "不接受的Content-Type类型: %s".formatted(e)); + } + + /** + * 处理请求方法错误的情况 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public Response handler(HttpRequestMethodNotSupportedException e) { + log.debug(String.format("请求错误(%s): %s", e.getClass().getName(), e)); + return Response.error(ServiceCode.InvalidRequest); + } +} \ No newline at end of file diff --git a/rition-center/api/src/main/java/rition/backend/api/interceptor/ResponseIdInterceptor.java b/rition-center/api/src/main/java/rition/backend/api/interceptor/ResponseIdInterceptor.java new file mode 100644 index 0000000..16051ed --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/interceptor/ResponseIdInterceptor.java @@ -0,0 +1,50 @@ +package rition.backend.api.interceptor; + +import jakarta.annotation.Nonnull; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import rition.backend.annotation.WithRequestIdResponse; +import rition.backend.util.ObjectUtils; +import rition.backend.util.StringUtils; + +import java.util.UUID; + +/** + * ResponseId的拦截器,为当前请求生成一个RequestId,并将其放入HttpServletRequest中的Attribute上下文中, + * 同时设置HttpServletResponse的Header + */ +@Slf4j +@Component +public class ResponseIdInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(@Nonnull HttpServletRequest request, + @Nonnull HttpServletResponse response, + @Nonnull Object handler) { + + if (!(handler instanceof HandlerMethod handlerMethod)) { + return true; + } + + var methodAnnotation = handlerMethod.getMethodAnnotation(WithRequestIdResponse.class); + var classAnnotation = handlerMethod + .getMethod() + .getDeclaringClass() + .getAnnotation(WithRequestIdResponse.class); + + if (ObjectUtils.atLeaseOneNonNull(methodAnnotation, classAnnotation)) { + var existsRequestId = response.getHeader("X-Request-ID"); + if (StringUtils.isEmpty(existsRequestId)) { + var requestId = UUID.randomUUID().toString(); + response.setHeader("X-Request-ID", requestId); + request.setAttribute("X-Request-ID", requestId); + } + } + + return true; + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/interceptor/TokenInterceptor.java b/rition-center/api/src/main/java/rition/backend/api/interceptor/TokenInterceptor.java new file mode 100644 index 0000000..85c2d4c --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/interceptor/TokenInterceptor.java @@ -0,0 +1,58 @@ +package rition.backend.api.interceptor; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Nonnull; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import rition.backend.annotation.RequireToken; + +import java.io.IOException; + +@Slf4j +@Component +public class TokenInterceptor implements HandlerInterceptor { + + private final ObjectMapper objectMapper; + + public TokenInterceptor(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public boolean preHandle(@Nonnull HttpServletRequest request, + @Nonnull HttpServletResponse response, + @Nonnull Object handler) throws Exception { + + if (!(handler instanceof HandlerMethod handlerMethod)) { + return true; + } + + // 方法上的RequireToken + var methodAnnotation = handlerMethod.getMethodAnnotation(RequireToken.class); + if (methodAnnotation == null) { + // class上的RequireToken + var classAnnotation = handlerMethod.getMethod().getDeclaringClass().getAnnotation(RequireToken.class); + if (classAnnotation == null) { + return true; + } else { + if (!classAnnotation.require()) { + return true; + } + } + } else { + if (!methodAnnotation.require()) { + return true; + } + } + + // 验证token + var token = request.getHeader("token"); + + + return true; + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/resolver/RequestIdArgumentResolver.java b/rition-center/api/src/main/java/rition/backend/api/resolver/RequestIdArgumentResolver.java new file mode 100644 index 0000000..283ef6e --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/resolver/RequestIdArgumentResolver.java @@ -0,0 +1,58 @@ +package rition.backend.api.resolver; + +import jakarta.annotation.Nonnull; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import rition.backend.annotation.paramter.RequestId; + +import java.util.UUID; + +/** + * 自动将request注入到controller的方法参数中,使用@RequestId标注后,将RequestId注入到参数中 + */ +@Slf4j +@Component +public class RequestIdArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(RequestId.class); + } + + @Override + public Object resolveArgument(@Nonnull MethodParameter parameter, ModelAndViewContainer mavContainer, + @Nonnull NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + + var request = webRequest.getNativeRequest(HttpServletRequest.class); + var response = webRequest.getNativeResponse(HttpServletResponse.class); + assert request != null; + assert response != null; + + // 如果Attribute上下文和ResponseHeader都有RequestId,则现在生成一个新的 + // 相应的方法已经使用@WithRequestIdResponse注解在拦截器中设置, + // 则其实可以断言Attribute上下文和ResponseHeader都有RequestId + String requestId = (String) request.getAttribute("X-Request-ID"); + if (requestId == null) { + requestId = response.getHeader("X-Request-ID"); + if (requestId == null) { + requestId = UUID.randomUUID().toString(); + response.setHeader("X-Request-ID", requestId); + } + + request.setAttribute("X-Request-ID", requestId); + return requestId; + } else { + if (response.getHeader("X-Request-ID") == null) { + response.setHeader("X-Request-ID", requestId); + } + } + + return requestId; + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/resolver/TokenArgumentResolver.java b/rition-center/api/src/main/java/rition/backend/api/resolver/TokenArgumentResolver.java new file mode 100644 index 0000000..06bbe36 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/resolver/TokenArgumentResolver.java @@ -0,0 +1,29 @@ +package rition.backend.api.resolver; + +import jakarta.annotation.Nonnull; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import rition.backend.annotation.paramter.Token; + +@Slf4j +@Component +public class TokenArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(Token.class); + } + + @Override + public Object resolveArgument(@Nonnull MethodParameter parameter, ModelAndViewContainer mavContainer, + @Nonnull NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + var httpServletResponse = webRequest.getNativeRequest(HttpServletRequest.class); + assert httpServletResponse != null; + return httpServletResponse.getHeader("token"); + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/DataCollectingController.java b/rition-center/api/src/main/java/rition/backend/api/v1/DataCollectingController.java new file mode 100644 index 0000000..121b16e --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/v1/DataCollectingController.java @@ -0,0 +1,24 @@ +package rition.backend.api.v1; + +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 rition.backend.annotation.paramter.RequestId; +import rition.backend.annotation.WithRequestIdResponse; +import rition.backend.api.v1.dto.request.MonitorDataUploadRequest; +import rition.backend.api.v1.dto.response.Response; + +import java.util.List; + +@RestController +@RequestMapping("/metric") +public class DataCollectingController { + + @PostMapping("/put") + @WithRequestIdResponse + public Response putData(@RequestBody List request, + @RequestId String requestId) { + return Response.success(); + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/request/MonitorDataUploadRequest.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/request/MonitorDataUploadRequest.java new file mode 100644 index 0000000..3122b4b --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/request/MonitorDataUploadRequest.java @@ -0,0 +1,29 @@ + +package rition.backend.api.v1.dto.request; + +import lombok.Data; + +import java.util.Map; + +@Data +public class MonitorDataUploadRequest { + /** + * 指标名 + */ + private String metric; + + /** + * 数据标签 + */ + private Map tags; + + /** + * 时间戳 + */ + private Long timestamp; + + /** + * 值 + */ + private Float value; +} diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/Response.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/Response.java new file mode 100644 index 0000000..7d28cc8 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/Response.java @@ -0,0 +1,130 @@ +package rition.backend.api.v1.dto.response; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import rition.common.exception.code.ServiceCode; + +import java.util.Objects; + +/** + * 通用的响应 + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Response { + + /** + * 业务响应码,用于表示请求处理的结果 + */ + protected final int code; + + /** + * 响应信息文本 + */ + protected final String message; + + /** + * 响应数据体 + */ + protected final T data; + + /** + * @param code 业务响应码,用于表示请求处理的结果 + * @param message 响应信息文本 + * @param data 响应数据体 + */ + public Response(int code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + } + + public Response(Response response) { + this.code = response.code; + this.message = response.message; + this.data = response.data; + } + + public static Response success() { + return success(null); + } + + public static Response success(T data) { + return new Response<>(ServiceCode.Ok.getCode(), "ok", data); + } + + public static Response success(int code, T data) { + return new Response<>(code, "ok", data); + } + + public static Response success(int code, String msg, T data) { + return new Response<>(code, msg, data); + } + + public static Response error(ServiceCode code) { + return new Response<>(code.getCode(), code.getMsg(), null); + } + + public static Response error(int code) { + var codes = ServiceCode.values(); + for (var serviceCode : codes) { + if (serviceCode.getCode() == code) { + return Response.error(serviceCode); + } + } + + return Response.error(ServiceCode.UnknownErr); + } + + public static Response error(int code, String message) { + return new Response<>(code, message, null); + } + + public static Response error(ServiceCode code, String message) { + return new Response<>(code.getCode(), message, null); + } + + public static Response error(int code, String message, T data) { + return new Response<>(code, message, data); + } + + public static Response error(ServiceCode code, String message, T data) { + return new Response<>(code.getCode(), message, data); + } + + public int code() { + return code; + } + + public String message() { + return message; + } + + public T data() { + return data; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (Response) obj; + return this.code == that.code && + Objects.equals(this.message, that.message) && + Objects.equals(this.data, that.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, data); + } + + @Override + public String toString() { + return "Response[" + + "code=" + code + ", " + + "Message=" + message + ", " + + "data=" + data + ']'; + } + +} \ No newline at end of file diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ResponseWithRequestId.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ResponseWithRequestId.java new file mode 100644 index 0000000..47529cf --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ResponseWithRequestId.java @@ -0,0 +1,37 @@ +package rition.backend.api.v1.dto.response; + +import lombok.Getter; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class ResponseWithRequestId extends Response { + + private String requestId; + + /** + * @param code 响应码 + * @param message 响应信息 + * @param data 响应数据 + */ + public ResponseWithRequestId(int code, String message, T data) { + super(code, message, data); + } + + public ResponseWithRequestId(Response response) { + super(response); + } + + public String initUUID() { + this.requestId = UUID.randomUUID().toString(); + return this.requestId; + } + + public static ResponseWithRequestId from(Response originResponse) { + var response = new ResponseWithRequestId<>(originResponse); + response.initUUID(); + return response; + } +} diff --git a/rition-center/api/src/main/java/rition/backend/configure/WebAppConfig.java b/rition-center/api/src/main/java/rition/backend/configure/WebAppConfig.java new file mode 100644 index 0000000..72b7b6c --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/configure/WebAppConfig.java @@ -0,0 +1,36 @@ +package rition.backend.configure; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; +import rition.backend.api.interceptor.ResponseIdInterceptor; +import rition.backend.api.resolver.RequestIdArgumentResolver; + +import java.util.List; + +@Configuration +@SpringBootConfiguration +public class WebAppConfig extends WebMvcConfigurationSupport { + + private final RequestIdArgumentResolver requestIdArgumentResolver; + private final ResponseIdInterceptor requestIdInterceptor; + + public WebAppConfig(RequestIdArgumentResolver requestIdArgumentResolver, + ResponseIdInterceptor requestIdInterceptor) { + this.requestIdArgumentResolver = requestIdArgumentResolver; + this.requestIdInterceptor = requestIdInterceptor; + } + + @Override + protected void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(requestIdArgumentResolver); + } + + @Override + protected void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(requestIdInterceptor) + .addPathPatterns("/**"); + } +} diff --git a/rition-center/api/src/main/java/rition/backend/util/ObjectUtils.java b/rition-center/api/src/main/java/rition/backend/util/ObjectUtils.java new file mode 100644 index 0000000..f3bc06d --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/util/ObjectUtils.java @@ -0,0 +1,27 @@ +package rition.backend.util; + +public class ObjectUtils { + public static boolean allNull(Object ...objects) { + for (var obj : objects) { + if (obj != null) { + return false; + } + } + + return true; + } + + public static boolean allNonNull(Object ...objects) { + for (var obj : objects) { + if (obj == null) { + return false; + } + } + + return true; + } + + public static boolean atLeaseOneNonNull(Object ...objects) { + return !allNull(objects); + } +} diff --git a/rition-center/api/src/main/java/rition/backend/util/StringUtils.java b/rition-center/api/src/main/java/rition/backend/util/StringUtils.java new file mode 100644 index 0000000..c134612 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/util/StringUtils.java @@ -0,0 +1,7 @@ +package rition.backend.util; + +public class StringUtils { + public static boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } +} diff --git a/rition-center/api/src/main/resources/application.yml b/rition-center/api/src/main/resources/application.yml new file mode 100644 index 0000000..0c11785 --- /dev/null +++ b/rition-center/api/src/main/resources/application.yml @@ -0,0 +1,2 @@ +server: + port: 22019 \ No newline at end of file diff --git a/rition-center/common/pom.xml b/rition-center/common/pom.xml new file mode 100644 index 0000000..3944548 --- /dev/null +++ b/rition-center/common/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + net.rition + rition-center + ${revision} + + + common + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/rition-center/common/src/main/java/rition/common/exception/ServiceException.java b/rition-center/common/src/main/java/rition/common/exception/ServiceException.java new file mode 100644 index 0000000..874dfe9 --- /dev/null +++ b/rition-center/common/src/main/java/rition/common/exception/ServiceException.java @@ -0,0 +1,46 @@ +package rition.common.exception; + + +import rition.common.exception.code.ServiceCode; + +import java.util.Objects; + +public class ServiceException extends RuntimeException { + private final int code; + + public ServiceException(ServiceCode code) { + this(code, code.getMsg()); + } + + public ServiceException(ServiceCode code, String message) { + super(message); + this.code = code.getCode(); + } + + public ServiceException(int code) { + this(Objects.requireNonNull(ServiceCode.valueOf(code))); + } + + public ServiceException(int code, String message) { + super(message); + this.code = code; + } + + public ServiceCode getCode() { + return ServiceCode.valueOf(code); + } + + public int getCodeValue() { + return code; + } + + /** + * 直接按错误码抛出异常 + * + * @param code 错误码 + * @throws ServiceException . + */ + public static void error(int code) throws ServiceException { + throw new ServiceException(code); + } +} diff --git a/rition-center/common/src/main/java/rition/common/exception/code/ServiceCode.java b/rition-center/common/src/main/java/rition/common/exception/code/ServiceCode.java new file mode 100644 index 0000000..ba592ad --- /dev/null +++ b/rition-center/common/src/main/java/rition/common/exception/code/ServiceCode.java @@ -0,0 +1,36 @@ +package rition.common.exception.code; + +import lombok.Getter; + +@Getter +public enum ServiceCode { + // common + Ok(0, "成功"), + + ApiNotImplement(10_00_00, "接口未实现"), + RequestTooFast(10_00_01, "请求过快"), + InvalidRequest(10_00_02, "非法请求"), + ParamWrong(10_00_03, "参数错误"), + PermissionDenied(10_00_04, "权限不足"), + TokenInvalid(10_00_05, "用户凭据无效,登录态失效"), + UnknownErr(10_00_06, "服务器内部错误"); + + private final int code; + + private final String msg; + + ServiceCode(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public static ServiceCode valueOf(int code) { + for (var serviceCode : ServiceCode.values()) { + if (serviceCode.code == code) { + return serviceCode; + } + } + + return null; + } +} diff --git a/rition-center/compose.yaml b/rition-center/compose.yaml new file mode 100644 index 0000000..0baad47 --- /dev/null +++ b/rition-center/compose.yaml @@ -0,0 +1 @@ +services: diff --git a/rition-center/pom.xml b/rition-center/pom.xml new file mode 100644 index 0000000..e69c91f --- /dev/null +++ b/rition-center/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + net.rition + rition-center + ${revision} + pom + rition + rition + + api + service + common + + + + 0.0.1-SNAPSHOT + + 17 + 17 + 17 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.fasterxml.jackson.core + jackson-annotations + + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.3.0 + + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/rition-center/service/collector/pom.xml b/rition-center/service/collector/pom.xml new file mode 100644 index 0000000..aba9b9a --- /dev/null +++ b/rition-center/service/collector/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + net.rition + service + ${revision} + + + collector + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/rition-center/service/collector/src/main/java/rition/service/collector/DataCollectorService.java b/rition-center/service/collector/src/main/java/rition/service/collector/DataCollectorService.java new file mode 100644 index 0000000..bc20d67 --- /dev/null +++ b/rition-center/service/collector/src/main/java/rition/service/collector/DataCollectorService.java @@ -0,0 +1,4 @@ +package rition.service.collector; + +public class DataCollectorService { +} diff --git a/rition-center/service/monitor/pom.xml b/rition-center/service/monitor/pom.xml new file mode 100644 index 0000000..56781e3 --- /dev/null +++ b/rition-center/service/monitor/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + net.rition + service + ${revision} + + + monitor + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/rition-center/service/monitor/src/main/java/rition/service/monitor/MonitorService.java b/rition-center/service/monitor/src/main/java/rition/service/monitor/MonitorService.java new file mode 100644 index 0000000..db7cc71 --- /dev/null +++ b/rition-center/service/monitor/src/main/java/rition/service/monitor/MonitorService.java @@ -0,0 +1,4 @@ +package rition.service.monitor; + +public class MonitorService { +} diff --git a/rition-center/service/notify/pom.xml b/rition-center/service/notify/pom.xml new file mode 100644 index 0000000..16de805 --- /dev/null +++ b/rition-center/service/notify/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + net.rition + service + ${revision} + + + notify + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/rition-center/service/notify/src/main/java/rition/service/notify/NotifyService.java b/rition-center/service/notify/src/main/java/rition/service/notify/NotifyService.java new file mode 100644 index 0000000..cb99e17 --- /dev/null +++ b/rition-center/service/notify/src/main/java/rition/service/notify/NotifyService.java @@ -0,0 +1,4 @@ +package rition.service.notify; + +public class NotifyService { +} diff --git a/rition-center/service/pom.xml b/rition-center/service/pom.xml new file mode 100644 index 0000000..299bd35 --- /dev/null +++ b/rition-center/service/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + net.rition + rition-center + ${revision} + + + service + pom + + collector + monitor + notify + + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/rition-panel/.gitignore b/rition-panel/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/rition-panel/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/rition-panel/README.md b/rition-panel/README.md new file mode 100644 index 0000000..a62d186 --- /dev/null +++ b/rition-panel/README.md @@ -0,0 +1,3 @@ +# rition-panel + +rition的面板 \ No newline at end of file diff --git a/rition-panel/index.html b/rition-panel/index.html new file mode 100644 index 0000000..8388c4b --- /dev/null +++ b/rition-panel/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Vue + + +
+ + + diff --git a/rition-panel/package.json b/rition-panel/package.json new file mode 100644 index 0000000..163aab5 --- /dev/null +++ b/rition-panel/package.json @@ -0,0 +1,18 @@ +{ + "name": "rition-panel", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.4.21" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "vite": "^5.2.0" + } +} diff --git a/rition-panel/public/vite.svg b/rition-panel/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/rition-panel/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rition-panel/src/App.vue b/rition-panel/src/App.vue new file mode 100644 index 0000000..341dbf0 --- /dev/null +++ b/rition-panel/src/App.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/rition-panel/src/assets/vue.svg b/rition-panel/src/assets/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/rition-panel/src/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rition-panel/src/components/HelloWorld.vue b/rition-panel/src/components/HelloWorld.vue new file mode 100644 index 0000000..f5e4f53 --- /dev/null +++ b/rition-panel/src/components/HelloWorld.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/rition-panel/src/main.js b/rition-panel/src/main.js new file mode 100644 index 0000000..2425c0f --- /dev/null +++ b/rition-panel/src/main.js @@ -0,0 +1,5 @@ +import { createApp } from 'vue' +import './style.css' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/rition-panel/src/style.css b/rition-panel/src/style.css new file mode 100644 index 0000000..bb131d6 --- /dev/null +++ b/rition-panel/src/style.css @@ -0,0 +1,79 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/rition-panel/vite.config.js b/rition-panel/vite.config.js new file mode 100644 index 0000000..05c1740 --- /dev/null +++ b/rition-panel/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/rition-panel/yarn.lock b/rition-panel/yarn.lock new file mode 100644 index 0000000..ee17beb --- /dev/null +++ b/rition-panel/yarn.lock @@ -0,0 +1,424 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/parser@^7.24.4": + version "7.24.5" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + +"@esbuild/darwin-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" + integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== + +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + +"@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@rollup/rollup-android-arm-eabi@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz#1a32112822660ee104c5dd3a7c595e26100d4c2d" + integrity sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ== + +"@rollup/rollup-android-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz#5aeef206d65ff4db423f3a93f71af91b28662c5b" + integrity sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw== + +"@rollup/rollup-darwin-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz#6b66aaf003c70454c292cd5f0236ebdc6ffbdf1a" + integrity sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw== + +"@rollup/rollup-darwin-x64@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz#f64fc51ed12b19f883131ccbcea59fc68cbd6c0b" + integrity sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz#1a7641111be67c10111f7122d1e375d1226cbf14" + integrity sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A== + +"@rollup/rollup-linux-arm-musleabihf@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz#c93fd632923e0fee25aacd2ae414288d0b7455bb" + integrity sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg== + +"@rollup/rollup-linux-arm64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz#fa531425dd21d058a630947527b4612d9d0b4a4a" + integrity sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A== + +"@rollup/rollup-linux-arm64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz#8acc16f095ceea5854caf7b07e73f7d1802ac5af" + integrity sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz#94e69a8499b5cf368911b83a44bb230782aeb571" + integrity sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ== + +"@rollup/rollup-linux-riscv64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz#7ef1c781c7e59e85a6ce261cc95d7f1e0b56db0f" + integrity sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg== + +"@rollup/rollup-linux-s390x-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz#f15775841c3232fca9b78cd25a7a0512c694b354" + integrity sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g== + +"@rollup/rollup-linux-x64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz#b521d271798d037ad70c9f85dd97d25f8a52e811" + integrity sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ== + +"@rollup/rollup-linux-x64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz#9254019cc4baac35800991315d133cc9fd1bf385" + integrity sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q== + +"@rollup/rollup-win32-arm64-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz#27f65a89f6f52ee9426ec11e3571038e4671790f" + integrity sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA== + +"@rollup/rollup-win32-ia32-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz#a2fbf8246ed0bb014f078ca34ae6b377a90cb411" + integrity sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ== + +"@rollup/rollup-win32-x64-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz#5a2d08b81e8064b34242d5cc9973ef8dd1e60503" + integrity sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w== + +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@vitejs/plugin-vue@^5.0.4": + version "5.0.4" + resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37" + integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== + +"@vue/compiler-core@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.26.tgz#d507886520e83a6f8339ed55ed0b2b5d84b44b73" + integrity sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ== + dependencies: + "@babel/parser" "^7.24.4" + "@vue/shared" "3.4.26" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.0" + +"@vue/compiler-dom@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz#acc7b788b48152d087d4bb9e655b795e3dbec554" + integrity sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA== + dependencies: + "@vue/compiler-core" "3.4.26" + "@vue/shared" "3.4.26" + +"@vue/compiler-sfc@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz#c679f206829954c3c078d8a9be76d0098b8377ae" + integrity sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw== + dependencies: + "@babel/parser" "^7.24.4" + "@vue/compiler-core" "3.4.26" + "@vue/compiler-dom" "3.4.26" + "@vue/compiler-ssr" "3.4.26" + "@vue/shared" "3.4.26" + estree-walker "^2.0.2" + magic-string "^0.30.10" + postcss "^8.4.38" + source-map-js "^1.2.0" + +"@vue/compiler-ssr@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz#22842d8adfff972d87bb798b8d496111f7f814b5" + integrity sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ== + dependencies: + "@vue/compiler-dom" "3.4.26" + "@vue/shared" "3.4.26" + +"@vue/reactivity@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.26.tgz#1191f543809d4c93e5b3e842ba83022350a3f205" + integrity sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ== + dependencies: + "@vue/shared" "3.4.26" + +"@vue/runtime-core@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.26.tgz#51ee971cb700370a67e5a510c4a84eff7491d658" + integrity sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw== + dependencies: + "@vue/reactivity" "3.4.26" + "@vue/shared" "3.4.26" + +"@vue/runtime-dom@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz#179aa7c8dc964112e6d096bc8ec5f361111009a1" + integrity sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw== + dependencies: + "@vue/runtime-core" "3.4.26" + "@vue/shared" "3.4.26" + csstype "^3.1.3" + +"@vue/server-renderer@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.26.tgz#6d0c6b0366bfe0232579aea00e3ff6784e5a1c60" + integrity sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw== + dependencies: + "@vue/compiler-ssr" "3.4.26" + "@vue/shared" "3.4.26" + +"@vue/shared@3.4.26": + version "3.4.26" + resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.26.tgz#f17854fb1faf889854aed4b23b60e86a8cab6403" + integrity sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ== + +csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +esbuild@^0.20.1: + version "0.20.2" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" + integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== + optionalDependencies: + "@esbuild/aix-ppc64" "0.20.2" + "@esbuild/android-arm" "0.20.2" + "@esbuild/android-arm64" "0.20.2" + "@esbuild/android-x64" "0.20.2" + "@esbuild/darwin-arm64" "0.20.2" + "@esbuild/darwin-x64" "0.20.2" + "@esbuild/freebsd-arm64" "0.20.2" + "@esbuild/freebsd-x64" "0.20.2" + "@esbuild/linux-arm" "0.20.2" + "@esbuild/linux-arm64" "0.20.2" + "@esbuild/linux-ia32" "0.20.2" + "@esbuild/linux-loong64" "0.20.2" + "@esbuild/linux-mips64el" "0.20.2" + "@esbuild/linux-ppc64" "0.20.2" + "@esbuild/linux-riscv64" "0.20.2" + "@esbuild/linux-s390x" "0.20.2" + "@esbuild/linux-x64" "0.20.2" + "@esbuild/netbsd-x64" "0.20.2" + "@esbuild/openbsd-x64" "0.20.2" + "@esbuild/sunos-x64" "0.20.2" + "@esbuild/win32-arm64" "0.20.2" + "@esbuild/win32-ia32" "0.20.2" + "@esbuild/win32-x64" "0.20.2" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +magic-string@^0.30.10: + version "0.30.10" + resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" + integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +postcss@^8.4.38: + version "8.4.38" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + +rollup@^4.13.0: + version "4.17.2" + resolved "https://registry.npmmirror.com/rollup/-/rollup-4.17.2.tgz#26d1785d0144122277fdb20ab3a24729ae68301f" + integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.17.2" + "@rollup/rollup-android-arm64" "4.17.2" + "@rollup/rollup-darwin-arm64" "4.17.2" + "@rollup/rollup-darwin-x64" "4.17.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.17.2" + "@rollup/rollup-linux-arm-musleabihf" "4.17.2" + "@rollup/rollup-linux-arm64-gnu" "4.17.2" + "@rollup/rollup-linux-arm64-musl" "4.17.2" + "@rollup/rollup-linux-powerpc64le-gnu" "4.17.2" + "@rollup/rollup-linux-riscv64-gnu" "4.17.2" + "@rollup/rollup-linux-s390x-gnu" "4.17.2" + "@rollup/rollup-linux-x64-gnu" "4.17.2" + "@rollup/rollup-linux-x64-musl" "4.17.2" + "@rollup/rollup-win32-arm64-msvc" "4.17.2" + "@rollup/rollup-win32-ia32-msvc" "4.17.2" + "@rollup/rollup-win32-x64-msvc" "4.17.2" + fsevents "~2.3.2" + +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +vite@^5.2.0: + version "5.2.10" + resolved "https://registry.npmmirror.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7" + integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw== + dependencies: + esbuild "^0.20.1" + postcss "^8.4.38" + rollup "^4.13.0" + optionalDependencies: + fsevents "~2.3.3" + +vue@^3.4.21: + version "3.4.26" + resolved "https://registry.npmmirror.com/vue/-/vue-3.4.26.tgz#936c97e37672c737705d7bdfa62c31af18742269" + integrity sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg== + dependencies: + "@vue/compiler-dom" "3.4.26" + "@vue/compiler-sfc" "3.4.26" + "@vue/runtime-dom" "3.4.26" + "@vue/server-renderer" "3.4.26" + "@vue/shared" "3.4.26" diff --git a/rition-probe/client/client.go b/rition-probe/client/client.go new file mode 100644 index 0000000..83e1417 --- /dev/null +++ b/rition-probe/client/client.go @@ -0,0 +1,20 @@ +package client + +import "time" + +type Config struct { + CenterServer string `json:"centerServer,omitempty"` + HostName string `json:"hostName,omitempty"` + InstanceId string `json:"instanceId,omitempty"` + ReportInterval time.Duration `json:"reportInterval,omitempty"` +} + +type Client struct { + config Config +} + +func NetClient(config Config) *Client { + return &Client{ + config: config, + } +} diff --git a/rition-probe/client/http.go b/rition-probe/client/http.go new file mode 100644 index 0000000..9c93cd9 --- /dev/null +++ b/rition-probe/client/http.go @@ -0,0 +1,16 @@ +package client + +import ( + "time" +) + +type ReportDataItem struct { + Metric string `json:"metric,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + Timestamp time.Time `json:"timestamp"` + Value any `json:"value,omitempty"` +} + +func (c *Client) Report() { + +} diff --git a/rition-probe/go.mod b/rition-probe/go.mod new file mode 100644 index 0000000..19885e7 --- /dev/null +++ b/rition-probe/go.mod @@ -0,0 +1,16 @@ +module rition-probe + +go 1.22.0 + +require github.com/shirou/gopsutil/v3 v3.24.3 + +require ( + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + golang.org/x/sys v0.18.0 // indirect +) diff --git a/rition-probe/go.sum b/rition-probe/go.sum new file mode 100644 index 0000000..78dd000 --- /dev/null +++ b/rition-probe/go.sum @@ -0,0 +1,47 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= +github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/rition-probe/main.go b/rition-probe/main.go new file mode 100644 index 0000000..7905807 --- /dev/null +++ b/rition-probe/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/rition-probe/probe/cpu.go b/rition-probe/probe/cpu.go new file mode 100644 index 0000000..865b8c7 --- /dev/null +++ b/rition-probe/probe/cpu.go @@ -0,0 +1,8 @@ +package probe + +import "github.com/shirou/gopsutil/v3/cpu" + +func (p *Probe) CurrentCPUTotalPercent() float64 { + cpuPercents, _ := cpu.Percent(0, false) + return cpuPercents[0] +} diff --git a/rition-probe/probe/disk.go b/rition-probe/probe/disk.go new file mode 100644 index 0000000..7325a64 --- /dev/null +++ b/rition-probe/probe/disk.go @@ -0,0 +1,13 @@ +package probe + +import "github.com/shirou/gopsutil/v3/disk" + +func (p *Probe) DiskStatus(mount, device string) (*disk.UsageStat, *disk.IOCountersStat) { + diskStatus, _ := disk.Usage(mount) + ioCounters, _ := disk.IOCounters(device) + for _, stat := range ioCounters { + return diskStatus, &stat + } + + return nil, nil +} diff --git a/rition-probe/probe/disk_test.go b/rition-probe/probe/disk_test.go new file mode 100644 index 0000000..5867eb9 --- /dev/null +++ b/rition-probe/probe/disk_test.go @@ -0,0 +1,12 @@ +package probe + +import ( + "fmt" + "testing" +) + +func TestDiskUsage(t *testing.T) { + usage, counter := probeTest.DiskStatus("/", "/dev/nvme0n1p2") + fmt.Println(usage) + fmt.Println(counter) +} diff --git a/rition-probe/probe/host.go b/rition-probe/probe/host.go new file mode 100644 index 0000000..af59ab3 --- /dev/null +++ b/rition-probe/probe/host.go @@ -0,0 +1,10 @@ +package probe + +import ( + "github.com/shirou/gopsutil/v3/host" +) + +func (p *Probe) HostUpTime() uint64 { + upTime, _ := host.Uptime() + return upTime +} diff --git a/rition-probe/probe/network.go b/rition-probe/probe/network.go new file mode 100644 index 0000000..b391b15 --- /dev/null +++ b/rition-probe/probe/network.go @@ -0,0 +1,21 @@ +package probe + +import ( + "github.com/shirou/gopsutil/v3/net" +) + +func (p *Probe) GetNetworkCounterAll() []net.IOCountersStat { + stats, _ := net.IOCounters(true) + return stats +} + +func (p *Probe) GetNetworkCounterOne(name string) net.IOCountersStat { + stats, _ := net.IOCounters(true) + for _, stat := range stats { + if stat.Name == name { + return stat + } + } + + return net.IOCountersStat{} +} diff --git a/rition-probe/probe/network_test.go b/rition-probe/probe/network_test.go new file mode 100644 index 0000000..a0f0190 --- /dev/null +++ b/rition-probe/probe/network_test.go @@ -0,0 +1,13 @@ +package probe + +import ( + "fmt" + "testing" +) + +func TestProbe_GetNetworkCounter(t *testing.T) { + counters := probeTest.GetNetworkCounterAll() + for _, counter := range counters { + fmt.Println(counter) + } +} diff --git a/rition-probe/probe/probe.go b/rition-probe/probe/probe.go new file mode 100644 index 0000000..8c958ca --- /dev/null +++ b/rition-probe/probe/probe.go @@ -0,0 +1,11 @@ +package probe + +type Config struct { +} + +type Probe struct { +} + +func NewProbe() *Probe { + return &Probe{} +} diff --git a/rition-probe/probe/probe_test.go b/rition-probe/probe/probe_test.go new file mode 100644 index 0000000..566661d --- /dev/null +++ b/rition-probe/probe/probe_test.go @@ -0,0 +1,3 @@ +package probe + +var probeTest = Probe{} diff --git a/rition-probe/probe/ram_linux.go b/rition-probe/probe/ram_linux.go new file mode 100644 index 0000000..efed363 --- /dev/null +++ b/rition-probe/probe/ram_linux.go @@ -0,0 +1,10 @@ +//go:build linux + +package probe + +import "github.com/shirou/gopsutil/v3/mem" + +func (p *Probe) RamUsage() (uint64, uint64, uint64, uint64) { + memory, _ := mem.VirtualMemory() + return memory.Total, memory.Used, memory.Buffers, memory.Cached +} diff --git a/rition-probe/probe/ram_windows.go b/rition-probe/probe/ram_windows.go new file mode 100644 index 0000000..14a6493 --- /dev/null +++ b/rition-probe/probe/ram_windows.go @@ -0,0 +1,10 @@ +//go:build windows + +package probe + +import "github.com/shirou/gopsutil/v3/mem" + +func (p *Probe) RamUsage() (uint64, uint64, uint64, uint64) { + memory, _ := mem.VirtualMemory() + return memory.Total, memory.Used, memory.Buffers, memory.Cached +} diff --git a/rition-probe/service/service.go b/rition-probe/service/service.go new file mode 100644 index 0000000..418ffc2 --- /dev/null +++ b/rition-probe/service/service.go @@ -0,0 +1,22 @@ +package service + +import "time" + +type Config struct { + CenterServer string `json:"centerServer,omitempty"` + HostName string `json:"hostName,omitempty"` + InstanceId string `json:"instanceId,omitempty"` + ReportInterval time.Duration `json:"reportInterval,omitempty"` +} + +type Service struct { + config Config +} + +func NewService(config Config) *Service { + service := Service{ + config: config, + } + + return &service +} diff --git a/rition-testsuite/DockerFile b/rition-testsuite/DockerFile new file mode 100644 index 0000000..e69de29