Project Init
This commit is contained in:
65
.gitignore
vendored
Normal file
65
.gitignore
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
*/.settings/
|
||||
.DS_Store
|
||||
*/.idea/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
#*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
# dev
|
||||
# logserver-web/src/main/**/dev.properties
|
||||
# logserver-web.src.resources.filters.dev.properties
|
||||
|
||||
logserver-web/src/test/
|
||||
|
||||
# Intellij
|
||||
*.iml
|
||||
|
||||
### Maven template
|
||||
target/
|
||||
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM registry.cn-hangzhou.aliyuncs.com/xhzy/tomcat8:1.0.0
|
||||
COPY groot-meta-web/target/groot-meta.war /home/admin/tomcat/webapps/ROOT.war
|
||||
ENV spring.config.location classpath:/,optional:file:/etc/shaman/static.properties,optional:classpath:/config/,optional:file:./,optional:file:./config/
|
||||
CMD ["tomcat/bin/catalina.sh", "run"]
|
||||
31
groot-data-bank-api/pom.xml
Normal file
31
groot-data-bank-api/pom.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>groot-data-bank-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.shuwen.groot.api.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbstractRequest implements Serializable {
|
||||
/**
|
||||
* 请求ID
|
||||
*/
|
||||
private String requestId;
|
||||
/**
|
||||
* 调用方标识
|
||||
*/
|
||||
private String appId;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.shuwen.groot.api.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.shuwen.groot.api.enums.ErrorCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class Response<T> implements Serializable {
|
||||
/**
|
||||
* 请求ID
|
||||
*/
|
||||
protected String requestId;
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
protected Boolean success;
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
protected String code;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
protected String msg;
|
||||
/**
|
||||
* 详细返回结果
|
||||
*/
|
||||
protected T data;
|
||||
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public Response(String requestId, ErrorCode errorCode, String msg) {
|
||||
this(requestId, errorCode, msg, null);
|
||||
}
|
||||
|
||||
public Response(String requestId, ErrorCode errorCode, String msg, T data) {
|
||||
this(requestId, errorCode == ErrorCode.PROCESS_SUCCESS, errorCode.getId(), msg, data);
|
||||
}
|
||||
|
||||
public Response(String requestId, Boolean success, String code, String msg, T data) {
|
||||
this.requestId = requestId;
|
||||
this.success = success;
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> Response<T> succeed() {
|
||||
return new Response<>(null, ErrorCode.PROCESS_SUCCESS, "处理成功");
|
||||
}
|
||||
|
||||
public static <T> Response<T> succeed(String requestId) {
|
||||
return new Response<>(requestId, ErrorCode.PROCESS_SUCCESS, "处理成功");
|
||||
}
|
||||
|
||||
public static <T> Response<T> succeed(T data) {
|
||||
return new Response<>(null, ErrorCode.PROCESS_SUCCESS, "处理成功", data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> succeed(String requestId, T data) {
|
||||
return new Response<>(requestId, ErrorCode.PROCESS_SUCCESS, "处理成功", data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(ErrorCode errorCode, String msg) {
|
||||
return new Response<>(null, errorCode, msg);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(String requestId, ErrorCode errorCode, String msg) {
|
||||
return new Response<>(requestId, errorCode, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.shuwen.groot.api.dto.request;
|
||||
|
||||
import com.shuwen.groot.api.dto.AbstractRequest;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:56
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class DeleteMaterialRequest extends AbstractRequest {
|
||||
/**
|
||||
* 素材ID
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 所属图谱
|
||||
*/
|
||||
private String graph;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.shuwen.groot.api.dto.request;
|
||||
|
||||
import com.shuwen.groot.api.dto.AbstractRequest;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:56
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class UpdateMaterialRequest extends AbstractRequest {
|
||||
/**
|
||||
* 素材ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 素材名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 素材内容
|
||||
*/
|
||||
private String content = "#content";
|
||||
/**
|
||||
* 所属图谱
|
||||
*/
|
||||
private String graph;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.shuwen.groot.api.dto.request;
|
||||
|
||||
import com.shuwen.groot.api.dto.AbstractRequest;
|
||||
import com.shuwen.groot.api.enums.MaterialType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:56
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadMaterialRequest extends AbstractRequest {
|
||||
/**
|
||||
* 素材名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 素材URL地址
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 素材内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 素材缩略图地址
|
||||
*/
|
||||
private String cover;
|
||||
/**
|
||||
* 素材类型
|
||||
*/
|
||||
private MaterialType type;
|
||||
/**
|
||||
* 素材来源
|
||||
*/
|
||||
private String source;
|
||||
/**
|
||||
* 所属图谱
|
||||
*/
|
||||
private String graph;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.shuwen.groot.api.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Created on 2020/4/9
|
||||
*
|
||||
* @author Kenn
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ErrorCode {
|
||||
/**
|
||||
* 处理成功
|
||||
*/
|
||||
PROCESS_SUCCESS("PO-10000"),
|
||||
/**
|
||||
* 参数为空
|
||||
*/
|
||||
EMPTY_PARAMS("PO-10001"),
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
PARAMS_ERROR("PO-10002"),
|
||||
/**
|
||||
* 数据已存在
|
||||
*/
|
||||
EXISTED("PO-10003"),
|
||||
/**
|
||||
* 数据不存在
|
||||
*/
|
||||
ABSENT("PO-10004"),
|
||||
/**
|
||||
* 内部错误
|
||||
*/
|
||||
INTERNAL_ERROR("PO-10005"),
|
||||
/**
|
||||
* 不支持错误
|
||||
*/
|
||||
NOT_SUPPORTED("PO-10006"),
|
||||
/**
|
||||
* 无效数据
|
||||
*/
|
||||
INVALID("PO-10007"),
|
||||
/**
|
||||
* 其他异常
|
||||
*/
|
||||
OTHER_ERROR("PO-50000");
|
||||
|
||||
private final String id;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.shuwen.groot.api.enums;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 17:20
|
||||
*/
|
||||
public enum MaterialType {
|
||||
/**
|
||||
* 图片
|
||||
*/
|
||||
IMAGE,
|
||||
/**
|
||||
* 视频
|
||||
*/
|
||||
VIDEO,
|
||||
/**
|
||||
* 音频
|
||||
*/
|
||||
AUDIO,
|
||||
/**
|
||||
* 文本
|
||||
*/
|
||||
DOCUMENT
|
||||
}
|
||||
52
groot-data-bank-common/pom.xml
Normal file
52
groot-data-bank-common/pom.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>groot-data-bank-common</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.shuwen.groot.common.base;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public final class Preconditions {
|
||||
|
||||
private Preconditions() {
|
||||
}
|
||||
|
||||
public static void checkNotEmpty(String str, InternalErrorCode code, Object errorMessage) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNotEmpty(String str, InternalErrorCode code, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
throw new MaterialException(code, Strings.lenientFormat(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkEmpty(Collection<?> coll, InternalErrorCode code, Object errorMessage) {
|
||||
if (CollectionUtils.isNotEmpty(coll)) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkEmpty(Collection<?> coll, InternalErrorCode code, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (CollectionUtils.isNotEmpty(coll)) {
|
||||
throw new MaterialException(code, Strings.lenientFormat(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNotEmpty(Collection<?> coll, InternalErrorCode code, Object errorMessage) {
|
||||
if (CollectionUtils.isEmpty(coll)) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNull(Object obj, InternalErrorCode code, Object errorMessage) {
|
||||
if (obj != null) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNotNull(Object obj, InternalErrorCode code, Object errorMessage) {
|
||||
if (obj == null) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkExpression(boolean expression, InternalErrorCode code, Object errorMessage) {
|
||||
if (!expression) {
|
||||
throw new MaterialException(code, String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkExpression(boolean expression, InternalErrorCode code, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (!expression) {
|
||||
throw new MaterialException(code, Strings.lenientFormat(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.shuwen.groot.common.enums;
|
||||
|
||||
import com.shuwen.groot.api.enums.ErrorCode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum InternalErrorCode {
|
||||
/**
|
||||
* 调用正常
|
||||
*/
|
||||
SUCCESS(ErrorCode.PROCESS_SUCCESS),
|
||||
/**
|
||||
* OTS异常
|
||||
*/
|
||||
OSS_ERROR(ErrorCode.INTERNAL_ERROR),
|
||||
/**
|
||||
* 发送HTTP异常
|
||||
*/
|
||||
HTTP_ERROR(ErrorCode.INTERNAL_ERROR),
|
||||
/**
|
||||
* ES请求异常
|
||||
*/
|
||||
ELASTIC_ERROR(ErrorCode.INTERNAL_ERROR),
|
||||
/**
|
||||
* 其他错误
|
||||
*/
|
||||
OTHER_ERROR(ErrorCode.INTERNAL_ERROR),
|
||||
/**
|
||||
* 参数为空
|
||||
*/
|
||||
EMPTY_PARAMS(ErrorCode.EMPTY_PARAMS),
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
PARAMS_ERROR(ErrorCode.PARAMS_ERROR),
|
||||
/**
|
||||
* 数据已存在
|
||||
*/
|
||||
EXISTED(ErrorCode.EXISTED),
|
||||
/**
|
||||
* 数据不存在
|
||||
*/
|
||||
ABSENT(ErrorCode.ABSENT),
|
||||
/**
|
||||
* 不支持操作
|
||||
*/
|
||||
NOT_SUPPORTED(ErrorCode.NOT_SUPPORTED),
|
||||
/**
|
||||
* 无效的
|
||||
*/
|
||||
INVALID(ErrorCode.INVALID);
|
||||
|
||||
private final ErrorCode code;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.shuwen.groot.common.exception;
|
||||
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Getter
|
||||
public class MaterialException extends RuntimeException {
|
||||
|
||||
private final InternalErrorCode errorCode;
|
||||
|
||||
public MaterialException(InternalErrorCode errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public MaterialException(InternalErrorCode errorCode, String message) {
|
||||
super(message);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public MaterialException(InternalErrorCode errorCode, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shuwen.groot.common.function;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Procedure {
|
||||
|
||||
void apply();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shuwen.groot.common.utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class IDUtils {
|
||||
|
||||
public static String getUUID() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.shuwen.groot.common.utils;
|
||||
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class OssUrlUtils {
|
||||
|
||||
public static Pair<String, String> extractHostPath(String requestUrl) {
|
||||
String host;
|
||||
String path;
|
||||
try {
|
||||
URL url = new URL(requestUrl);
|
||||
host = url.getHost();
|
||||
path = url.getPath();
|
||||
return Pair.of(host, path);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new MaterialException(InternalErrorCode.PARAMS_ERROR, "不合法的URL");
|
||||
}
|
||||
}
|
||||
|
||||
public static String extractBucket(String host) {
|
||||
int index = host.indexOf(".");
|
||||
return host.substring(0, index);
|
||||
}
|
||||
|
||||
public static String extractKey(String path) {
|
||||
return path.substring(1);
|
||||
}
|
||||
|
||||
public static String extractSuffix(String key) {
|
||||
int index = key.lastIndexOf(".");
|
||||
return key.substring(index + 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.shuwen.groot.common.utils;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class RegExUtils {
|
||||
|
||||
private static final String NAME_REGEX = "^[0-9a-zA-Z_]+$";
|
||||
|
||||
private static final String DESC_REGEX = "[\u4e00-\u9fa5]+";
|
||||
|
||||
private static final String REL_NAME_REGEX = "[a-zA-Z\u4e00-\u9fa5]+";
|
||||
|
||||
public static boolean validateName(String name) {
|
||||
return Pattern.matches(NAME_REGEX, name);
|
||||
}
|
||||
|
||||
public static boolean validateDesc(String desc) {
|
||||
return Pattern.matches(DESC_REGEX, desc);
|
||||
}
|
||||
|
||||
public static boolean validateRelName(String desc) {
|
||||
return Pattern.matches(REL_NAME_REGEX, desc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.shuwen.groot.common.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class SignUtils {
|
||||
|
||||
public static String sign(long timestamp, String secret) throws Exception {
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
|
||||
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
||||
return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.shuwen.groot.common.utils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class TimeUtils {
|
||||
|
||||
private static final ZoneOffset ZONE_OFFSET = ZoneOffset.ofHours(8);
|
||||
|
||||
private static final ZoneId ZONE_ID = ZoneId.of("Asia/Shanghai");
|
||||
|
||||
public static LocalDateTime convert(long millisecond) {
|
||||
return new Date(millisecond).toInstant().atOffset(ZONE_OFFSET).toLocalDateTime();
|
||||
}
|
||||
|
||||
public static long convert(LocalDateTime localDateTime) {
|
||||
return localDateTime.atZone(ZONE_ID).toInstant().toEpochMilli();
|
||||
}
|
||||
}
|
||||
180
groot-data-bank-manager/pom.xml
Normal file
180
groot-data-bank-manager/pom.xml
Normal file
@@ -0,0 +1,180 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>groot-data-bank-manager</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- project start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-common</artifactId>
|
||||
</dependency>
|
||||
<!-- project end -->
|
||||
|
||||
<!-- spring boot start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- spring boot end -->
|
||||
|
||||
<!-- xhzy start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.ops</groupId>
|
||||
<artifactId>shaman-configmap</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.kubernetes</groupId>
|
||||
<artifactId>client-java-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.kubernetes</groupId>
|
||||
<artifactId>client-java-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.search</groupId>
|
||||
<artifactId>search-proxy-api</artifactId>
|
||||
</dependency>
|
||||
<!-- xhzy end -->
|
||||
|
||||
<!-- aliyun start -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
</dependency>
|
||||
<!-- aliyun end -->
|
||||
|
||||
<!-- service start -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-recipes</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jline</groupId>
|
||||
<artifactId>jline</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- service end -->
|
||||
|
||||
<!-- jackson start -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<!-- jackson end -->
|
||||
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.leopard</groupId>
|
||||
<artifactId>javahost</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.shuwen.groot.manager.config;
|
||||
|
||||
import com.shuwen.groot.manager.constant.Constant;
|
||||
import com.shuwen.search.proxy.api.service.ICrudService;
|
||||
import com.shuwen.search.proxy.api.service.IFilterService;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/5 15:50
|
||||
*/
|
||||
@Configuration
|
||||
public class DubboConfig {
|
||||
|
||||
@DubboReference(version = "${dubbo.service.search.version}", group = "${dubbo.service.search.group}", retries = Constant.MAX_RETRY_TIME)
|
||||
private ICrudService crudService;
|
||||
|
||||
@DubboReference(version = "${dubbo.service.search.version}", group = "${dubbo.service.search.group}", retries = Constant.MAX_RETRY_TIME)
|
||||
private IFilterService filterService;
|
||||
|
||||
@Bean
|
||||
public ICrudService crudService() {
|
||||
return crudService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IFilterService filterService() {
|
||||
return filterService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.shuwen.groot.manager.config;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Configuration
|
||||
public class OkHttpConfig {
|
||||
|
||||
private static final long TIMEOUT = 30L;
|
||||
|
||||
private static final int MAX_IDLE_CONNECTIONS = 800;
|
||||
|
||||
private static final long KEEP_ALIVE_DURATION = 5;
|
||||
|
||||
@Bean
|
||||
public OkHttpClient okHttpClient(ConnectionPool pool) {
|
||||
return new OkHttpClient.Builder()
|
||||
.retryOnConnectionFailure(true)
|
||||
.connectionPool(pool)
|
||||
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
|
||||
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConnectionPool pool() {
|
||||
return new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.shuwen.groot.manager.config.base;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Project: meta-sales-manage
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/11/12 17:36
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "oss")
|
||||
public class OssConfig {
|
||||
|
||||
private String endpoint;
|
||||
|
||||
private String bucket;
|
||||
|
||||
private String ossUrl;
|
||||
|
||||
private String prefix;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.shuwen.groot.manager.configmap;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.shuwen.ops.shaman.configmap.Config;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Slf4j
|
||||
public class DingAlertConfig {
|
||||
|
||||
private static final String DATA_ID = "ding_alert";
|
||||
|
||||
static {
|
||||
Config.addListener(DATA_ID, DingAlertConfig::analyzeData);
|
||||
}
|
||||
|
||||
private static synchronized void analyzeData(String configInfo) {
|
||||
log.info("get ding alert config: {}", configInfo);
|
||||
JSONObject config = JSONObject.parseObject(configInfo);
|
||||
if (config.containsKey("alert")) {
|
||||
alert = config.getBoolean("alert");
|
||||
}
|
||||
if (config.containsKey("biz")) {
|
||||
biz = config.getString("biz");
|
||||
}
|
||||
if (config.containsKey("targets")) {
|
||||
targets = Sets.newHashSet(config.getJSONArray("targets").toJavaList(String.class));
|
||||
}
|
||||
if (config.containsKey("webhook")) {
|
||||
webhook = config.getString("webhook");
|
||||
}
|
||||
if (config.containsKey("secret")) {
|
||||
secret = config.getString("secret");
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean alert;
|
||||
|
||||
private static String biz;
|
||||
|
||||
private static Set<String> targets;
|
||||
|
||||
private static String webhook;
|
||||
|
||||
private static String secret;
|
||||
|
||||
public static boolean alert() {
|
||||
return alert != null && alert;
|
||||
}
|
||||
|
||||
public static String biz() {
|
||||
return biz;
|
||||
}
|
||||
|
||||
public static Set<String> targets() {
|
||||
return targets == null ? Sets.newHashSet() : targets;
|
||||
}
|
||||
|
||||
public static String webhook() {
|
||||
return webhook;
|
||||
}
|
||||
|
||||
public static String secret() {
|
||||
return secret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shuwen.groot.manager.constant;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
public class Constant {
|
||||
|
||||
public static final int INIT_RETRY_TIME = 0;
|
||||
|
||||
public static final int MAX_RETRY_TIME = 3;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.shuwen.groot.manager.ding;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.shuwen.groot.common.utils.SignUtils;
|
||||
import com.shuwen.groot.manager.configmap.DingAlertConfig;
|
||||
import com.shuwen.groot.manager.http.HttpHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DingTalkNotifier {
|
||||
|
||||
@Resource
|
||||
private HttpHandler httpHandler;
|
||||
|
||||
public MarkDownMessage build(String info, String graph, String type) {
|
||||
MarkDownMessage message = new MarkDownMessage();
|
||||
message.setTitle("groot-meta");
|
||||
message.add(MarkDownMessage.getHeaderText(2, "groot-meta"));
|
||||
List<String> items = Lists.newArrayList();
|
||||
items.add("biz: " + DingAlertConfig.biz());
|
||||
items.add("env: " + System.getenv("DEPLOY_ENV"));
|
||||
items.add("graph: " + graph);
|
||||
items.add("type: " + type);
|
||||
items.add("alert:" + info);
|
||||
message.add(MarkDownMessage.getUnOrderListText(items));
|
||||
message.setAtMobiles(DingAlertConfig.targets());
|
||||
return message;
|
||||
}
|
||||
|
||||
public void notify(MarkDownMessage message) {
|
||||
if (DingAlertConfig.alert()) {
|
||||
try {
|
||||
httpHandler.doPost(url(), null, null, message.toString());
|
||||
} catch (Exception e) {
|
||||
log.error("can not alert message: {}", message.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String url() throws Exception {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String sign = SignUtils.sign(timestamp, DingAlertConfig.secret());
|
||||
return DingAlertConfig.webhook() + "×tamp=" + timestamp + "&sign=" + sign;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.shuwen.groot.manager.ding;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Setter
|
||||
public class MarkDownMessage {
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 文本
|
||||
*/
|
||||
private final List<String> content = Lists.newArrayList();
|
||||
/**
|
||||
* 需要@的手机号
|
||||
*/
|
||||
private Set<String> atMobiles;
|
||||
/**
|
||||
* 是否@所有人
|
||||
*/
|
||||
private boolean isAtAll = false;
|
||||
|
||||
public void add(String text) {
|
||||
this.content.add(text);
|
||||
}
|
||||
|
||||
public static String getHeaderText(int headerType, String text) {
|
||||
if (headerType >= 1 && headerType <= 6) {
|
||||
StringBuilder numbers = new StringBuilder();
|
||||
for (int i = 0; i < headerType; ++i) {
|
||||
numbers.append("#");
|
||||
}
|
||||
return numbers + " " + text;
|
||||
} else {
|
||||
throw new IllegalArgumentException("headerType should be in [1, 6]");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUnOrderListText(List<String> unorderItem) {
|
||||
if (unorderItem.isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < unorderItem.size() - 1; ++i) {
|
||||
builder.append("- ").append(unorderItem.get(i)).append("\n");
|
||||
}
|
||||
builder.append("- ").append(unorderItem.get(unorderItem.size() - 1));
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Map<String, Object> markdown = Maps.newHashMap();
|
||||
markdown.put("title", this.title);
|
||||
markdown.put("text", Joiner.on('\n').join(content));
|
||||
|
||||
Map<String, Object> items = Maps.newHashMap();
|
||||
items.put("msgtype", "markdown");
|
||||
items.put("markdown", markdown);
|
||||
|
||||
Map<String, Object> atItems = Maps.newHashMap();
|
||||
if (CollectionUtils.isNotEmpty(atMobiles)) {
|
||||
atItems.put("atMobiles", atMobiles);
|
||||
}
|
||||
atItems.put("isAtAll", isAtAll);
|
||||
|
||||
items.put("at", atItems);
|
||||
return JSON.toJSONString(items);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.shuwen.groot.manager.http;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.manager.constant.Constant;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.shuwen.groot.common.base.Preconditions.checkExpression;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Component
|
||||
public class HttpHandler {
|
||||
|
||||
@Resource
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
public String doPost(String url, JSONObject queries, JSONObject headers, String body) {
|
||||
String exactUrl = url(url, queries);
|
||||
if (StringUtils.isEmpty(exactUrl)) {
|
||||
return null;
|
||||
}
|
||||
RequestBody requestBody = RequestBody.create(body, MediaType.parse("application/json; charset=utf-8"));
|
||||
Request request = builder(exactUrl, headers)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
return execute(request, Constant.INIT_RETRY_TIME);
|
||||
}
|
||||
|
||||
public String doGet(String url, JSONObject queries, JSONObject headers) {
|
||||
String exactUrl = url(url, queries);
|
||||
if (StringUtils.isEmpty(exactUrl)) {
|
||||
return null;
|
||||
}
|
||||
Request request = builder(exactUrl, headers)
|
||||
.build();
|
||||
return execute(request, Constant.INIT_RETRY_TIME);
|
||||
}
|
||||
|
||||
private String url(String url, JSONObject queries) {
|
||||
HttpUrl httpUrl = HttpUrl.parse(url);
|
||||
if (httpUrl == null) {
|
||||
return null;
|
||||
}
|
||||
HttpUrl.Builder urlBuilder = httpUrl.newBuilder();
|
||||
if (MapUtils.isNotEmpty(queries)) {
|
||||
queries.forEach((key, value) -> urlBuilder.addQueryParameter(key, (String) value));
|
||||
}
|
||||
return urlBuilder.toString();
|
||||
}
|
||||
|
||||
private Request.Builder builder(String url, JSONObject headers) {
|
||||
Request.Builder builder = new Request.Builder().url(url);
|
||||
if (MapUtils.isNotEmpty(headers)) {
|
||||
headers.forEach((key, value) -> builder.addHeader(key, (String) value));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private String execute(Request request, int retryTimes) {
|
||||
Response response = null;
|
||||
try {
|
||||
response = okHttpClient.newCall(request).execute();
|
||||
ResponseBody body = response.body();
|
||||
if (body == null) {
|
||||
return null;
|
||||
}
|
||||
return body.string();
|
||||
} catch (Exception e) {
|
||||
checkExpression(retryTimes < Constant.MAX_RETRY_TIME, InternalErrorCode.HTTP_ERROR, e);
|
||||
return execute(request, ++retryTimes);
|
||||
} finally {
|
||||
if (Objects.nonNull(response)) {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.shuwen.groot.manager.oss;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.CopyObjectResult;
|
||||
import com.aliyun.oss.model.GetObjectRequest;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import com.shuwen.groot.common.utils.OssUrlUtils;
|
||||
import com.shuwen.groot.manager.config.base.OssConfig;
|
||||
import com.shuwen.groot.manager.constant.Constant;
|
||||
import com.shuwen.ops.shaman.configmap.util.ConfigMapUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Project: meta-sales-manage
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/11/12 17:36
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class OssHandler {
|
||||
|
||||
private static final Long DURATION_SECONDS = 3600L;
|
||||
|
||||
private OSS oss;
|
||||
|
||||
private String env;
|
||||
|
||||
@Autowired
|
||||
private OssConfig ossConfig;
|
||||
|
||||
public String materialUrlPrefix = "groot:";
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.env = System.getenv("DEPLOY_ENV");
|
||||
ConfigMapUtils.processAkSkChange(s -> {
|
||||
log.info("aksk is changed, need to reconstruct oss client");
|
||||
if (oss != null) {
|
||||
oss.shutdown();
|
||||
}
|
||||
oss = new OSSClientBuilder()
|
||||
.build(ossConfig.getEndpoint(), ConfigMapUtils.getAk(), ConfigMapUtils.getSk());
|
||||
});
|
||||
materialUrlPrefix = "groot-" + (env == null ? "test:" : env.toLowerCase(Locale.ROOT) + ":");
|
||||
}
|
||||
|
||||
public String copy(String sourceBucket, String sourceKey, String destinationKeyLatterPart) {
|
||||
String destinationKey = ossConfig.getPrefix() + "/" + destinationKeyLatterPart;
|
||||
copy(sourceBucket, sourceKey, ossConfig.getBucket(), destinationKey, Constant.INIT_RETRY_TIME);
|
||||
return materialUrlPrefix + "/" + destinationKey;
|
||||
}
|
||||
|
||||
public String getImageInfo(String bucket, String key) {
|
||||
OSSObject ossObject = null;
|
||||
try {
|
||||
GetObjectRequest request = new GetObjectRequest(bucket, key);
|
||||
request.setProcess("image/info");
|
||||
ossObject = oss.getObject(request);
|
||||
return IOUtils.toString(ossObject.getResponse().getContent(), StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
log.error("get image info fail, bucket: {}, key: {}", bucket, key, e);
|
||||
throw new MaterialException(InternalErrorCode.OSS_ERROR, "获取图片信息失败");
|
||||
} finally {
|
||||
IOUtils.closeQuietly(ossObject);
|
||||
}
|
||||
}
|
||||
|
||||
public String convert(String url) {
|
||||
return url.replaceFirst(materialUrlPrefix, ossConfig.getOssUrl());
|
||||
}
|
||||
|
||||
public String sign(String url) {
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(url);
|
||||
String host = hostPath.getKey();
|
||||
if (!host.contains("oss-cn-hangzhou")) {
|
||||
return url;
|
||||
}
|
||||
String bucket = OssUrlUtils.extractBucket(hostPath.getKey());
|
||||
String key = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
return sign(bucket, key);
|
||||
}
|
||||
|
||||
private CopyObjectResult copy(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey, int retryTimes) {
|
||||
try {
|
||||
return oss.copyObject(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
|
||||
} catch (Exception e) {
|
||||
if (retryTimes >= 3) {
|
||||
log.error("can not copy object, source bucket: {}, source key: {}, destination bucket: {}, destination key: {}",
|
||||
sourceBucketName, sourceKey, destinationBucketName, destinationKey, e);
|
||||
throw new MaterialException(InternalErrorCode.OSS_ERROR, "oss拷贝异常");
|
||||
}
|
||||
return copy(sourceBucketName, sourceKey, destinationBucketName, destinationKey, ++retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
private String sign(String bucket, String key) {
|
||||
Date expiration = new Date(new Date().getTime() + DURATION_SECONDS * 1000);
|
||||
URL signUrl = sign(bucket, key, expiration, Constant.INIT_RETRY_TIME);
|
||||
|
||||
String newUrl = StringUtils.replace(signUrl.toString(), "oss-cn-hangzhou-internal", "oss-cn-hangzhou");
|
||||
if (StringUtils.isNotEmpty(env) && env.equals("PROD")) {
|
||||
return StringUtils.replace(newUrl, "http", "https", 1);
|
||||
} else {
|
||||
return newUrl;
|
||||
}
|
||||
}
|
||||
|
||||
private URL sign(String bucketName, String objectName, Date expiration, int retryTimes) {
|
||||
try {
|
||||
return oss.generatePresignedUrl(bucketName, objectName, expiration);
|
||||
} catch (Exception e) {
|
||||
if (retryTimes >= 3) {
|
||||
log.error("can not sign url, bucket: {}, object: {}", bucketName, objectName, e);
|
||||
throw new MaterialException(InternalErrorCode.OSS_ERROR, "OSS地址签名异常");
|
||||
}
|
||||
return sign(bucketName, objectName, expiration, ++retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
if (oss != null) {
|
||||
oss.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
83
groot-data-bank-service/pom.xml
Normal file
83
groot-data-bank-service/pom.xml
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>groot-data-bank-service</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring boot start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<!-- spring boot end -->
|
||||
|
||||
<!-- project start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-manager</artifactId>
|
||||
</dependency>
|
||||
<!-- project end -->
|
||||
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.shuwen.groot.service;
|
||||
|
||||
import com.shuwen.groot.api.dto.request.DeleteMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UpdateMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UploadMaterialRequest;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:55
|
||||
*/
|
||||
public interface IMaterialService {
|
||||
/**
|
||||
* 上传素材
|
||||
*
|
||||
* @param request 上传请求
|
||||
* @return 结果
|
||||
*/
|
||||
Object upload(UploadMaterialRequest request);
|
||||
|
||||
/**
|
||||
* 更新素材
|
||||
*
|
||||
* @param request 更新请求
|
||||
* @return 结果
|
||||
*/
|
||||
Object update(UpdateMaterialRequest request);
|
||||
|
||||
/**
|
||||
* 删除素材
|
||||
*
|
||||
* @param request 删除请求
|
||||
* @return 结果
|
||||
*/
|
||||
Object delete(DeleteMaterialRequest request);
|
||||
|
||||
/**
|
||||
* 获取素材
|
||||
*
|
||||
* @param materialId 素材ID
|
||||
* @param graph 图谱名称
|
||||
* @param convertUrl 是否地址转换
|
||||
* @param signUrl 是否加签
|
||||
* @return 结果
|
||||
*/
|
||||
Object get(String materialId, String graph, boolean convertUrl, boolean signUrl);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.shuwen.groot.service.dto.http;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 17:06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AudioInfo {
|
||||
|
||||
private double audioDuration;
|
||||
|
||||
private int audioChannel;
|
||||
|
||||
private int audioSampleRate;
|
||||
|
||||
private int audioBitRate;
|
||||
|
||||
private double fileSize;
|
||||
|
||||
private String format;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.shuwen.groot.service.dto.http;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 17:06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ImageInfo {
|
||||
|
||||
private String format;
|
||||
|
||||
private double size;
|
||||
|
||||
private int height;
|
||||
|
||||
private int width;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.shuwen.groot.service.dto.http;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 17:06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class VideoInfo {
|
||||
|
||||
private double videoDuration;
|
||||
|
||||
private int videoWidth;
|
||||
|
||||
private int videoHeight;
|
||||
|
||||
private String videoDar;
|
||||
|
||||
private int videoBitRate;
|
||||
|
||||
private int videoVoiceRate;
|
||||
|
||||
private int videoFps;
|
||||
|
||||
private double audioDuration;
|
||||
|
||||
private int audioChannel;
|
||||
|
||||
private int audioSampleRate;
|
||||
|
||||
private int audioBitRate;
|
||||
|
||||
private double fileSize;
|
||||
|
||||
private String format;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.shuwen.groot.service.dto.material;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/3 10:44
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AudioMaterial extends Material {
|
||||
/**
|
||||
* 音频时长
|
||||
*/
|
||||
@JsonProperty("audio_duration")
|
||||
@JSONField(name = "audio_duration")
|
||||
private double audioDuration;
|
||||
/**
|
||||
* 音频通道
|
||||
*/
|
||||
@JsonProperty("audio_channel")
|
||||
@JSONField(name = "audio_channel")
|
||||
private int audioChannel;
|
||||
/**
|
||||
* 音频采样率
|
||||
*/
|
||||
@JsonProperty("audio_sample_rate")
|
||||
@JSONField(name = "audio_sample_rate")
|
||||
private int audioSampleRate;
|
||||
/**
|
||||
* 音频比特率
|
||||
*/
|
||||
@JsonProperty("audio_bit_rate")
|
||||
@JSONField(name = "audio_bit_rate")
|
||||
private int audioBitRate;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.shuwen.groot.service.dto.material;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/3 10:45
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ImageMaterial extends Material{
|
||||
/**
|
||||
* 高
|
||||
*/
|
||||
private int height;
|
||||
/**
|
||||
* 宽
|
||||
*/
|
||||
private int width;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.shuwen.groot.service.dto.material;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.shuwen.groot.api.enums.MaterialType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/3 10:44
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class Material {
|
||||
/**
|
||||
* 素材ID
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 素材类型
|
||||
*/
|
||||
private MaterialType type;
|
||||
/**
|
||||
* 素材来源
|
||||
*/
|
||||
private String source;
|
||||
/**
|
||||
* 素材名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 素材地址
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 素材封面
|
||||
*/
|
||||
private String cover;
|
||||
/**
|
||||
* 素材格式
|
||||
*/
|
||||
private String format;
|
||||
/**
|
||||
* 素材大小
|
||||
*/
|
||||
private double size;
|
||||
/**
|
||||
* 素材信息
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 关联实体信息
|
||||
*/
|
||||
@JsonProperty("related_entity_list")
|
||||
@JSONField(name = "related_entity_list")
|
||||
private List<RelatedEntity> relatedEntityList;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonProperty("create_time")
|
||||
@JSONField(name = "create_time")
|
||||
private long createTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonProperty("update_time")
|
||||
@JSONField(name = "update_time")
|
||||
private long updateTime;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.shuwen.groot.service.dto.material;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/3 11:43
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RelatedEntity {
|
||||
/**
|
||||
* 实体类型
|
||||
*/
|
||||
private String label;
|
||||
/**
|
||||
* 实体ID
|
||||
*/
|
||||
private String entityId;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.shuwen.groot.service.dto.material;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/3 10:45
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class VideoMaterial extends Material {
|
||||
/**
|
||||
* 高
|
||||
*/
|
||||
private int height;
|
||||
/**
|
||||
* 宽
|
||||
*/
|
||||
private int width;
|
||||
/**
|
||||
* 视频时长
|
||||
*/
|
||||
@JsonProperty("video_duration")
|
||||
@JSONField(name = "video_duration")
|
||||
private double videoDuration;
|
||||
/**
|
||||
* 视频高宽比
|
||||
*/
|
||||
@JsonProperty("video_dar")
|
||||
@JSONField(name = "video_dar")
|
||||
private String videoDar;
|
||||
/**
|
||||
* 视频比特率
|
||||
*/
|
||||
@JsonProperty("video_bit_rate")
|
||||
@JSONField(name = "video_bit_rate")
|
||||
private int videoBitRate;
|
||||
/**
|
||||
* 声速
|
||||
*/
|
||||
@JsonProperty("voice_rate")
|
||||
@JSONField(name = "voice_rate")
|
||||
private int voiceRate;
|
||||
/**
|
||||
* 视频每秒帧数
|
||||
*/
|
||||
@JsonProperty("video_fps")
|
||||
@JSONField(name = "video_fps")
|
||||
private int videoFps;
|
||||
/**
|
||||
* 音频时长
|
||||
*/
|
||||
@JsonProperty("audio_duration")
|
||||
@JSONField(name = "audio_duration")
|
||||
private double audioDuration;
|
||||
/**
|
||||
* 音频通道
|
||||
*/
|
||||
@JsonProperty("audio_channel")
|
||||
@JSONField(name = "audio_channel")
|
||||
private int audioChannel;
|
||||
/**
|
||||
* 音频采样率
|
||||
*/
|
||||
@JsonProperty("audio_sample_rate")
|
||||
@JSONField(name = "audio_sample_rate")
|
||||
private int audioSampleRate;
|
||||
/**
|
||||
* 音频比特率
|
||||
*/
|
||||
@JsonProperty("audio_bit_rate")
|
||||
@JSONField(name = "audio_bit_rate")
|
||||
private int audioBitRate;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.shuwen.groot.service.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.shuwen.groot.api.enums.MaterialType;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import com.shuwen.groot.manager.constant.Constant;
|
||||
import com.shuwen.groot.service.dto.material.AudioMaterial;
|
||||
import com.shuwen.groot.service.dto.material.ImageMaterial;
|
||||
import com.shuwen.groot.service.dto.material.Material;
|
||||
import com.shuwen.groot.service.dto.material.VideoMaterial;
|
||||
import com.shuwen.search.proxy.api.entity.base.FieldFilter;
|
||||
import com.shuwen.search.proxy.api.entity.dto.common.CrudReqDto;
|
||||
import com.shuwen.search.proxy.api.entity.dto.common.CrudRespDto;
|
||||
import com.shuwen.search.proxy.api.entity.dto.common.FilterReqDto;
|
||||
import com.shuwen.search.proxy.api.entity.dto.common.ItemsRespDto;
|
||||
import com.shuwen.search.proxy.api.entity.enums.FieldFilterTypeEnum;
|
||||
import com.shuwen.search.proxy.api.service.ICrudService;
|
||||
import com.shuwen.search.proxy.api.service.IFilterService;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.shuwen.groot.common.base.Preconditions.checkExpression;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/5 16:02
|
||||
*/
|
||||
@Component
|
||||
public class ElasticSearchHandler {
|
||||
|
||||
private static final String INDEX_PROJECT = "groot-data";
|
||||
|
||||
private static final String MATERIAL_INDEX_GROUP_SUFFIX = "material";
|
||||
|
||||
private static final String MATERIAL_INDEX_TYPE = "default";
|
||||
|
||||
@Resource
|
||||
private ICrudService crudService;
|
||||
|
||||
@Resource
|
||||
private IFilterService filterService;
|
||||
|
||||
public void add(Material material, String graph) {
|
||||
CrudReqDto crudReqDto = materialCrud(material.getId(), material.getType(), graph);
|
||||
crudReqDto.setContent(JSON.toJSONString(material));
|
||||
add(crudReqDto, Constant.INIT_RETRY_TIME);
|
||||
}
|
||||
|
||||
public Material get(String id, String graph) {
|
||||
FilterReqDto filterReqDto = new FilterReqDto();
|
||||
filterReqDto.setProject(INDEX_PROJECT);
|
||||
String indexGroup = graph + "_" + MATERIAL_INDEX_GROUP_SUFFIX;
|
||||
filterReqDto.setIndexGroup(indexGroup);
|
||||
filterReqDto.setIndex(graph + "_material_index");
|
||||
FieldFilter fieldFilter = new FieldFilter("_id", FieldFilterTypeEnum.TERM, id);
|
||||
filterReqDto.must(fieldFilter);
|
||||
List<Object> items = filter(filterReqDto, Constant.INIT_RETRY_TIME);
|
||||
if (items == null) {
|
||||
return null;
|
||||
}
|
||||
if (items.size() != 1) {
|
||||
return null;
|
||||
}
|
||||
JSONObject data = (JSONObject) JSON.toJSON(items.get(0));
|
||||
MaterialType materialType = EnumUtils.getEnum(MaterialType.class, data.getString("type"));
|
||||
switch (materialType) {
|
||||
case IMAGE:
|
||||
return data.toJavaObject(ImageMaterial.class);
|
||||
case AUDIO:
|
||||
return data.toJavaObject(AudioMaterial.class);
|
||||
case VIDEO:
|
||||
return data.toJavaObject(VideoMaterial.class);
|
||||
default:
|
||||
throw new MaterialException(InternalErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public void update(Material material, String graph) {
|
||||
CrudReqDto crudReqDto = materialCrud(material.getId(), material.getType(), graph);
|
||||
JSONObject content = new JSONObject()
|
||||
.fluentPut("name", material.getName())
|
||||
.fluentPut("content", null)
|
||||
.fluentPut("update_time", material.getUpdateTime());
|
||||
crudReqDto.setContent(content.toJSONString());
|
||||
update(crudReqDto, Constant.INIT_RETRY_TIME);
|
||||
}
|
||||
|
||||
public void delete(String id, MaterialType materialType, String graph) {
|
||||
CrudReqDto crudReqDto = materialCrud(id, materialType, graph);
|
||||
delete(crudReqDto, Constant.INIT_RETRY_TIME);
|
||||
}
|
||||
|
||||
private CrudReqDto materialCrud(String id, MaterialType materialType, String graph) {
|
||||
String indexGroup = graph + "_" + MATERIAL_INDEX_GROUP_SUFFIX;
|
||||
String index = materialType.name().toLowerCase(Locale.ROOT);
|
||||
CrudReqDto crudReqDto = new CrudReqDto();
|
||||
crudReqDto.setProject(INDEX_PROJECT);
|
||||
crudReqDto.setIndexGroup(indexGroup);
|
||||
crudReqDto.setIndex(index);
|
||||
crudReqDto.setType(MATERIAL_INDEX_TYPE);
|
||||
crudReqDto.setId(id);
|
||||
return crudReqDto;
|
||||
}
|
||||
|
||||
private void add(CrudReqDto reqDto, int retryTimes) {
|
||||
try {
|
||||
CrudRespDto respDto = crudService.add(reqDto);
|
||||
if (!respDto.getSucceed()) {
|
||||
throw new MaterialException(InternalErrorCode.ELASTIC_ERROR, respDto.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
checkExpression(retryTimes < Constant.MAX_RETRY_TIME, InternalErrorCode.ELASTIC_ERROR, e);
|
||||
add(reqDto, ++retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
private void update(CrudReqDto reqDto, int retryTimes) {
|
||||
try {
|
||||
CrudRespDto respDto = crudService.update(reqDto);
|
||||
if (!respDto.getSucceed()) {
|
||||
throw new MaterialException(InternalErrorCode.ELASTIC_ERROR, respDto.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
checkExpression(retryTimes < Constant.MAX_RETRY_TIME, InternalErrorCode.ELASTIC_ERROR, e);
|
||||
update(reqDto, ++retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
private void delete(CrudReqDto reqDto, int retryTimes) {
|
||||
try {
|
||||
CrudRespDto respDto = crudService.delete(reqDto);
|
||||
if (!respDto.getSucceed()) {
|
||||
throw new MaterialException(InternalErrorCode.ELASTIC_ERROR, respDto.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
checkExpression(retryTimes < Constant.MAX_RETRY_TIME, InternalErrorCode.ELASTIC_ERROR, e);
|
||||
delete(reqDto, ++retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> filter(FilterReqDto reqDto, int retryTimes) {
|
||||
try {
|
||||
ItemsRespDto respDto = filterService.filter(reqDto);
|
||||
if (!respDto.getSucceed()) {
|
||||
throw new MaterialException(InternalErrorCode.ELASTIC_ERROR, respDto.getMessage());
|
||||
}
|
||||
if (respDto.getData() != null) {
|
||||
return respDto.getData().getItems();
|
||||
}
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
checkExpression(retryTimes < Constant.MAX_RETRY_TIME, InternalErrorCode.ELASTIC_ERROR, e);
|
||||
return filter(reqDto, ++retryTimes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package com.shuwen.groot.service.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import com.shuwen.groot.common.utils.OssUrlUtils;
|
||||
import com.shuwen.groot.manager.http.HttpHandler;
|
||||
import com.shuwen.groot.manager.oss.OssHandler;
|
||||
import com.shuwen.groot.service.dto.http.AudioInfo;
|
||||
import com.shuwen.groot.service.dto.http.ImageInfo;
|
||||
import com.shuwen.groot.service.dto.http.VideoInfo;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/5 11:18
|
||||
*/
|
||||
@Component
|
||||
public class MaterialHandler {
|
||||
|
||||
@Resource
|
||||
private OssHandler ossHandler;
|
||||
|
||||
@Resource
|
||||
private HttpHandler httpHandler;
|
||||
|
||||
@Value("${media.utils.url}")
|
||||
private String mediaUtilUrl;
|
||||
|
||||
public String copy(String url, String id, String graph) {
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(url);
|
||||
|
||||
String sourceBucket = OssUrlUtils.extractBucket(hostPath.getKey());
|
||||
String sourceKey = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
|
||||
String suffix = OssUrlUtils.extractSuffix(sourceKey);
|
||||
String destinationKeyLatterPart = graph + "/material/" + id + "." + suffix;
|
||||
|
||||
return ossHandler.copy(sourceBucket, sourceKey, destinationKeyLatterPart);
|
||||
}
|
||||
|
||||
public String copyCover(String thumb, String id, String graph) {
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(thumb);
|
||||
|
||||
String sourceBucket = OssUrlUtils.extractBucket(hostPath.getKey());
|
||||
String sourceKey = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
|
||||
String suffix = OssUrlUtils.extractSuffix(sourceKey);
|
||||
String destinationKeyLatterPart = graph + "/thumb/" + id + "." + suffix;
|
||||
|
||||
return ossHandler.copy(sourceBucket, sourceKey, destinationKeyLatterPart);
|
||||
}
|
||||
|
||||
public ImageInfo getImageInfo(String url) {
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(url);
|
||||
String bucket = OssUrlUtils.extractBucket(hostPath.getKey());
|
||||
String key = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
String info = ossHandler.getImageInfo(bucket, key);
|
||||
if (StringUtils.isEmpty(info)) {
|
||||
throw new MaterialException(InternalErrorCode.OSS_ERROR, "无法获取image信息");
|
||||
}
|
||||
ImageInfo imageInfo = new ImageInfo();
|
||||
JSONObject infoJson = JSON.parseObject(info);
|
||||
long fileSize = 0;
|
||||
if (infoJson.containsKey("FileSize")) {
|
||||
JSONObject valueJson = infoJson.getJSONObject("FileSize");
|
||||
if (valueJson.containsKey("value")) {
|
||||
fileSize = valueJson.getLong("value");
|
||||
}
|
||||
}
|
||||
imageInfo.setSize(fileSize);
|
||||
|
||||
String format = null;
|
||||
if (infoJson.containsKey("Format")) {
|
||||
JSONObject valueJson = infoJson.getJSONObject("Format");
|
||||
if (valueJson.containsKey("value")) {
|
||||
format = valueJson.getString("value");
|
||||
}
|
||||
}
|
||||
imageInfo.setFormat(format);
|
||||
|
||||
int height = 0;
|
||||
if (infoJson.containsKey("ImageHeight")) {
|
||||
JSONObject valueJson = infoJson.getJSONObject("ImageHeight");
|
||||
if (valueJson.containsKey("value")) {
|
||||
height = valueJson.getIntValue("value");
|
||||
}
|
||||
}
|
||||
imageInfo.setHeight(height);
|
||||
|
||||
int width = 0;
|
||||
if (infoJson.containsKey("ImageWidth")) {
|
||||
JSONObject valueJson = infoJson.getJSONObject("ImageWidth");
|
||||
if (valueJson.containsKey("value")) {
|
||||
width = valueJson.getIntValue("value");
|
||||
}
|
||||
}
|
||||
imageInfo.setWidth(width);
|
||||
|
||||
return imageInfo;
|
||||
}
|
||||
|
||||
public AudioInfo getAudioInfo(String url) {
|
||||
JSONObject info = getInfo(url);
|
||||
if (info == null) {
|
||||
throw new MaterialException(InternalErrorCode.HTTP_ERROR, "无法获取audio信息");
|
||||
}
|
||||
AudioInfo audioInfo = info.toJavaObject(AudioInfo.class);
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(url);
|
||||
String key = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
String suffix = OssUrlUtils.extractSuffix(key);
|
||||
audioInfo.setFormat(suffix);
|
||||
return audioInfo;
|
||||
}
|
||||
|
||||
public VideoInfo getVideoInfo(String url) {
|
||||
JSONObject info = getInfo(url);
|
||||
if (info == null) {
|
||||
throw new MaterialException(InternalErrorCode.HTTP_ERROR, "无法获取video信息");
|
||||
}
|
||||
VideoInfo videoInfo = info.toJavaObject(VideoInfo.class);
|
||||
Pair<String, String> hostPath = OssUrlUtils.extractHostPath(url);
|
||||
String key = OssUrlUtils.extractKey(hostPath.getValue());
|
||||
String suffix = OssUrlUtils.extractSuffix(key);
|
||||
videoInfo.setFormat(suffix);
|
||||
return videoInfo;
|
||||
}
|
||||
|
||||
public String cover(String url) {
|
||||
String requestUrl = mediaUtilUrl + "/video/v5/thumb";
|
||||
JSONObject queries = new JSONObject()
|
||||
.fluentPut("url", url);
|
||||
String req = httpHandler.doGet(requestUrl, queries, new JSONObject());
|
||||
if (StringUtils.isEmpty(req)) {
|
||||
throw new MaterialException(InternalErrorCode.HTTP_ERROR, "指定video截帧结果为空");
|
||||
}
|
||||
JSONObject response = JSON.parseObject(req);
|
||||
if (!response.containsKey("code") || !response.getString("code").equals("200") || !response.containsKey("data")) {
|
||||
throw new MaterialException(InternalErrorCode.HTTP_ERROR, "指定video截帧失败");
|
||||
}
|
||||
JSONObject data = response.getJSONObject("data");
|
||||
if (!data.containsKey("out_url")) {
|
||||
throw new MaterialException(InternalErrorCode.HTTP_ERROR, "指定video截帧结果为空");
|
||||
}
|
||||
return data.getString("out_url");
|
||||
}
|
||||
|
||||
public String convert(String url) {
|
||||
return ossHandler.convert(url);
|
||||
}
|
||||
|
||||
public String sign(String url) {
|
||||
return ossHandler.sign(url);
|
||||
}
|
||||
|
||||
private JSONObject getInfo(String url) {
|
||||
String requestUrl = mediaUtilUrl + "/video/v2/info";
|
||||
JSONObject body = new JSONObject()
|
||||
.fluentPut("url", url)
|
||||
.fluentPut("isInternal", true);
|
||||
String req = httpHandler.doPost(requestUrl, new JSONObject(), new JSONObject(), body.toJSONString());
|
||||
if (StringUtils.isEmpty(req)) {
|
||||
return null;
|
||||
}
|
||||
JSONObject response = JSON.parseObject(req);
|
||||
if (!response.containsKey("code") || !response.getString("code").equals("200") || !response.containsKey("data")) {
|
||||
return null;
|
||||
}
|
||||
return response.getJSONObject("data");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.shuwen.groot.service.impl;
|
||||
|
||||
import com.shuwen.groot.api.dto.request.DeleteMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UpdateMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UploadMaterialRequest;
|
||||
import com.shuwen.groot.api.enums.MaterialType;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import com.shuwen.groot.service.IMaterialService;
|
||||
import com.shuwen.groot.service.dto.http.AudioInfo;
|
||||
import com.shuwen.groot.service.dto.http.ImageInfo;
|
||||
import com.shuwen.groot.service.dto.http.VideoInfo;
|
||||
import com.shuwen.groot.service.dto.material.AudioMaterial;
|
||||
import com.shuwen.groot.service.dto.material.ImageMaterial;
|
||||
import com.shuwen.groot.service.dto.material.Material;
|
||||
import com.shuwen.groot.service.dto.material.VideoMaterial;
|
||||
import com.shuwen.groot.service.handler.ElasticSearchHandler;
|
||||
import com.shuwen.groot.service.handler.MaterialHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.shuwen.groot.common.base.Preconditions.checkNotEmpty;
|
||||
import static com.shuwen.groot.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 17:06
|
||||
*/
|
||||
@Service
|
||||
public class MaterialServiceImpl implements IMaterialService {
|
||||
|
||||
@Resource
|
||||
private MaterialHandler materialHandler;
|
||||
|
||||
@Resource
|
||||
private ElasticSearchHandler elasticSearchHandler;
|
||||
|
||||
@Override
|
||||
public Object upload(UploadMaterialRequest request) {
|
||||
check(request);
|
||||
|
||||
String id = UUID.randomUUID().toString();
|
||||
|
||||
// 拷贝素材到素材库地址
|
||||
String url = materialHandler.copy(request.getUrl(), id, request.getGraph());
|
||||
|
||||
Material material;
|
||||
// 获取素材信息
|
||||
switch (request.getType()) {
|
||||
case IMAGE:
|
||||
ImageInfo imageInfo = materialHandler.getImageInfo(request.getUrl());
|
||||
ImageMaterial imageMaterial = new ImageMaterial();
|
||||
BeanUtils.copyProperties(imageInfo, imageMaterial);
|
||||
material = imageMaterial;
|
||||
break;
|
||||
case AUDIO:
|
||||
AudioInfo audioInfo = materialHandler.getAudioInfo(request.getUrl());
|
||||
AudioMaterial audioMaterial = new AudioMaterial();
|
||||
BeanUtils.copyProperties(audioInfo, audioMaterial);
|
||||
audioMaterial.setSize(audioInfo.getFileSize());
|
||||
material = audioMaterial;
|
||||
break;
|
||||
case VIDEO:
|
||||
VideoInfo videoInfo = materialHandler.getVideoInfo(request.getUrl());
|
||||
VideoMaterial videoMaterial = new VideoMaterial();
|
||||
BeanUtils.copyProperties(videoInfo, videoMaterial);
|
||||
videoMaterial.setSize(videoInfo.getFileSize());
|
||||
material = videoMaterial;
|
||||
break;
|
||||
default:
|
||||
throw new MaterialException(InternalErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
|
||||
// 基本信息
|
||||
material.setId(id);
|
||||
material.setUrl(url);
|
||||
material.setType(request.getType());
|
||||
material.setSource(request.getSource());
|
||||
material.setName(request.getName());
|
||||
material.setContent(request.getContent());
|
||||
|
||||
// 获取封面
|
||||
String cover = request.getCover();
|
||||
if (StringUtils.isEmpty(cover)) {
|
||||
if (request.getType() == MaterialType.VIDEO) {
|
||||
String serviceCover = materialHandler.cover(request.getUrl());
|
||||
cover = materialHandler.copyCover(serviceCover, id, request.getGraph());
|
||||
} else if (request.getType() == MaterialType.IMAGE) {
|
||||
cover = url;
|
||||
} else if (request.getType() == MaterialType.AUDIO) {
|
||||
cover = "groot-test:/meta-sales-manage/default/audio.png";
|
||||
}
|
||||
} else {
|
||||
cover = materialHandler.copyCover(cover, id, request.getGraph());
|
||||
}
|
||||
material.setCover(cover);
|
||||
|
||||
// 实体识别
|
||||
// TODO 待定
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
material.setCreateTime(time);
|
||||
material.setUpdateTime(time);
|
||||
|
||||
// 写入索引
|
||||
elasticSearchHandler.add(material, request.getGraph());
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object update(UpdateMaterialRequest request) {
|
||||
check(request);
|
||||
|
||||
// 从ES获取素材
|
||||
Material material = elasticSearchHandler.get(request.getId(), request.getGraph());
|
||||
checkNotNull(material, InternalErrorCode.ABSENT, "The point material is not exist");
|
||||
|
||||
// 更新名称或内容
|
||||
if (!StringUtils.equals(request.getName(), material.getName())) {
|
||||
material.setName(request.getName());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(request.getContent())) {
|
||||
if (!StringUtils.equals(request.getContent(), "#content")) {
|
||||
material.setContent(request.getContent());
|
||||
}
|
||||
} else {
|
||||
material.setContent(null);
|
||||
}
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
material.setUpdateTime(time);
|
||||
|
||||
// 更新ES
|
||||
elasticSearchHandler.update(material, request.getGraph());
|
||||
|
||||
return material.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object delete(DeleteMaterialRequest request) {
|
||||
check(request);
|
||||
|
||||
// 从ES获取素材
|
||||
Material material = elasticSearchHandler.get(request.getId(), request.getGraph());
|
||||
checkNotNull(material, InternalErrorCode.ABSENT, "The point material is not exist");
|
||||
|
||||
// 更新ES
|
||||
elasticSearchHandler.delete(material.getId(), material.getType(), request.getGraph());
|
||||
|
||||
return material.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String id, String graph, boolean convertUrl, boolean signUrl) {
|
||||
checkNotEmpty(id, InternalErrorCode.EMPTY_PARAMS, "The material id is empty");
|
||||
checkNotEmpty(graph, InternalErrorCode.EMPTY_PARAMS, "The graph is empty");
|
||||
|
||||
// 从ES获取素材
|
||||
Material material = elasticSearchHandler.get(id, graph);
|
||||
checkNotNull(material, InternalErrorCode.ABSENT, "The point material is not exist");
|
||||
|
||||
// 转换素材地址和封面
|
||||
if (convertUrl) {
|
||||
String url = materialHandler.convert(material.getUrl());
|
||||
if (signUrl) {
|
||||
url = materialHandler.sign(url);
|
||||
}
|
||||
material.setUrl(url);
|
||||
|
||||
if (StringUtils.isNotEmpty(material.getCover())) {
|
||||
String cover = materialHandler.convert(material.getCover());
|
||||
if (signUrl) {
|
||||
cover = materialHandler.sign(cover);
|
||||
}
|
||||
material.setCover(cover);
|
||||
}
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
private void check(UploadMaterialRequest request) {
|
||||
checkNotEmpty(request.getName(), InternalErrorCode.EMPTY_PARAMS, "The material name is empty");
|
||||
checkNotEmpty(request.getUrl(), InternalErrorCode.EMPTY_PARAMS, "The material url is empty");
|
||||
checkNotNull(request.getType(), InternalErrorCode.EMPTY_PARAMS, "The material type is empty");
|
||||
checkNotEmpty(request.getSource(), InternalErrorCode.EMPTY_PARAMS, "The material source is empty");
|
||||
checkNotEmpty(request.getGraph(), InternalErrorCode.EMPTY_PARAMS, "The graph is empty");
|
||||
}
|
||||
|
||||
private void check(UpdateMaterialRequest request) {
|
||||
checkNotEmpty(request.getId(), InternalErrorCode.EMPTY_PARAMS, "The material id is empty");
|
||||
checkNotEmpty(request.getName(), InternalErrorCode.EMPTY_PARAMS, "The material name is empty");
|
||||
checkNotEmpty(request.getGraph(), InternalErrorCode.EMPTY_PARAMS, "The graph is empty");
|
||||
}
|
||||
|
||||
private void check(DeleteMaterialRequest request) {
|
||||
checkNotEmpty(request.getId(), InternalErrorCode.EMPTY_PARAMS, "The material id is empty");
|
||||
checkNotEmpty(request.getGraph(), InternalErrorCode.EMPTY_PARAMS, "The graph is empty");
|
||||
}
|
||||
}
|
||||
222
groot-data-bank-web/pom.xml
Normal file
222
groot-data-bank-web/pom.xml
Normal file
@@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>groot-data-bank-web</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- project start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-service</artifactId>
|
||||
</dependency>
|
||||
<!-- project end -->
|
||||
|
||||
<!-- spring boot start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- spring boot end -->
|
||||
|
||||
<!-- micrometer start -->
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<!-- micrometer end -->
|
||||
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
|
||||
<!-- test start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- test end -->
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>offline</id>
|
||||
<properties>
|
||||
<activatedProperties>offline</activatedProperties>
|
||||
</properties>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>application*.yml</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>online</id>
|
||||
<properties>
|
||||
<activatedProperties>online</activatedProperties>
|
||||
</properties>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>application*.yml</exclude>
|
||||
<exclude>shaman-config/**</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<finalName>${project.parent.artifactId}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>application.yml</include>
|
||||
<include>application-${activatedProperties}.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>repackage</id>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-dependency-convergence</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<DependencyConvergence/>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.shuwen.groot;
|
||||
|
||||
import com.shuwen.ops.shaman.configmap.ShamanPropertySourceFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* Created on 2020/4/9
|
||||
*
|
||||
* @author Kenn
|
||||
*/
|
||||
@EnableCaching
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
@PropertySource(name = "k8s-app", value = "groot-meta", factory = ShamanPropertySourceFactory.class)
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||
return builder.sources(Application.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.shuwen.groot.controller.advice;
|
||||
|
||||
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.shuwen.groot.api.dto.Response;
|
||||
import com.shuwen.groot.api.enums.ErrorCode;
|
||||
import com.shuwen.groot.api.enums.MaterialType;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class GraphControllerAdvice {
|
||||
|
||||
@ExceptionHandler(InvalidFormatException.class)
|
||||
public Response<Object> handlerException(InvalidFormatException e) {
|
||||
Class<?> clazz = e.getTargetType();
|
||||
String message;
|
||||
if (clazz == MaterialType.class) {
|
||||
message = String.format("Material types are only supported: %s", Joiner.on(", ").join(MaterialType.values()));
|
||||
return Response.fail(ErrorCode.PARAMS_ERROR, message);
|
||||
} else {
|
||||
message = e.getMessage();
|
||||
return Response.fail(ErrorCode.OTHER_ERROR, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.shuwen.groot.controller.aspect;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.shuwen.groot.api.dto.AbstractRequest;
|
||||
import com.shuwen.groot.api.dto.Response;
|
||||
import com.shuwen.groot.api.enums.ErrorCode;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import com.shuwen.groot.common.exception.MaterialException;
|
||||
import com.shuwen.groot.common.utils.IDUtils;
|
||||
import com.shuwen.groot.controller.log.AccessLogContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@Aspect
|
||||
@Order(1)
|
||||
public class GlobalAspect {
|
||||
|
||||
private static final Set<InternalErrorCode> IGNORE_STACK_MESSAGE = Sets.newHashSet(
|
||||
InternalErrorCode.EMPTY_PARAMS,
|
||||
InternalErrorCode.PARAMS_ERROR,
|
||||
InternalErrorCode.ABSENT,
|
||||
InternalErrorCode.EXISTED,
|
||||
InternalErrorCode.NOT_SUPPORTED,
|
||||
InternalErrorCode.INVALID
|
||||
);
|
||||
|
||||
@Resource
|
||||
private HttpServletRequest httpServletRequest;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Around("execution(* com.shuwen.groot.controller.core..*.*(..))")
|
||||
public Object around(ProceedingJoinPoint pjd) throws Throwable {
|
||||
long start = System.currentTimeMillis();
|
||||
String requestId;
|
||||
|
||||
// 获取请求URL
|
||||
String uri = httpServletRequest.getRequestURI();
|
||||
// 解析URL Query Params
|
||||
Map<String, Object> params = getQueryParams(httpServletRequest);
|
||||
// 解析Header
|
||||
Map<String, Object> headers = getHeaders(httpServletRequest);
|
||||
|
||||
AbstractRequest request = null;
|
||||
Object[] args = pjd.getArgs();
|
||||
if (args != null && args.length > 0) {
|
||||
if (args[0] instanceof AbstractRequest) {
|
||||
request = ((AbstractRequest) args[0]);
|
||||
requestId = request.getRequestId();
|
||||
if (StringUtils.isEmpty(requestId)) {
|
||||
requestId = IDUtils.getUUID();
|
||||
}
|
||||
request.setRequestId(requestId);
|
||||
} else {
|
||||
requestId = IDUtils.getUUID();
|
||||
}
|
||||
} else {
|
||||
requestId = IDUtils.getUUID();
|
||||
}
|
||||
|
||||
Response<Object> response;
|
||||
try {
|
||||
Object result = pjd.proceed();
|
||||
if (result == null) {
|
||||
response = Response.succeed(requestId);
|
||||
} else if (result instanceof Response){
|
||||
response = (Response<Object>) result;
|
||||
response.setRequestId(requestId);
|
||||
} else {
|
||||
response = Response.succeed(requestId, result);
|
||||
}
|
||||
AccessLogContext.log(uri, params, headers, request, response, start);
|
||||
} catch (MaterialException e) {
|
||||
response = handleException(requestId, uri, params, headers, request, start, e);
|
||||
} catch (Exception e) {
|
||||
response = handleOtherException(requestId, uri, params, headers, request, start, e);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private Map<String, Object> getQueryParams(HttpServletRequest request) {
|
||||
String queryString = request.getQueryString();
|
||||
if (StringUtils.isEmpty(queryString)) {
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
return Splitter.on("&").splitToStream(queryString)
|
||||
.filter(Objects::nonNull).map(paramStr -> {
|
||||
if (StringUtils.isEmpty(paramStr)) {
|
||||
return null;
|
||||
}
|
||||
String[] segments = StringUtils.split(paramStr, "=", 2);
|
||||
if (segments.length == 1) {
|
||||
return null;
|
||||
}
|
||||
String valueStr = segments[1];
|
||||
if (valueStr.contains(",")) {
|
||||
return Pair.of(segments[0], valueStr.split(","));
|
||||
} else {
|
||||
return Pair.of(segments[0], valueStr);
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));
|
||||
}
|
||||
|
||||
private Map<String, Object> getHeaders(HttpServletRequest request) {
|
||||
Enumeration<String> enumeration = request.getHeaderNames();
|
||||
Map<String, Object> headers = new LinkedHashMap<>();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
String name = enumeration.nextElement();
|
||||
List<String> values = new ArrayList<>();
|
||||
Enumeration<String> valueEnum = request.getHeaders(name);
|
||||
while (valueEnum.hasMoreElements()) {
|
||||
String value = valueEnum.nextElement();
|
||||
values.add(value);
|
||||
}
|
||||
if (values.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
if (values.size() == 1) {
|
||||
headers.put(name, values.get(0));
|
||||
} else {
|
||||
headers.put(name, values);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private <T extends AbstractRequest> Response<Object> handleException(String requestId, String uri, Map<String, Object> params,
|
||||
Map<String, Object> headers, T request, long start, MaterialException e) {
|
||||
Response<Object> response;
|
||||
if (e.getErrorCode() != null) {
|
||||
response = Response.fail(requestId, e.getErrorCode().getCode(), e.getMessage());
|
||||
} else {
|
||||
response = Response.fail(requestId, ErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
if (IGNORE_STACK_MESSAGE.contains(e.getErrorCode())) {
|
||||
log.error("graph exception, uri: {}, request id: {}, error code: {}, error message: {}", uri, response.getRequestId(),
|
||||
e.getErrorCode(), e.getMessage());
|
||||
AccessLogContext.log(uri, params, headers, request, response, e.getErrorCode(), e.getMessage(), start);
|
||||
} else {
|
||||
log.error("graph exception, uri: {}, request id: {}", uri, response.getRequestId(), e);
|
||||
AccessLogContext.log(uri, params, headers, request, response, e.getErrorCode(), e, start);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private <T extends AbstractRequest> Response<Object> handleOtherException(String requestId, String uri, Map<String, Object> params,
|
||||
Map<String, Object> headers, T request, long start, Exception e) {
|
||||
Response<Object> response = Response.fail(requestId, ErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
log.error("other exception, uri: {}, request id: {}", uri, response.getRequestId(), e);
|
||||
AccessLogContext.log(uri, params, headers, request, response, InternalErrorCode.OTHER_ERROR, e, start);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.shuwen.groot.controller.core;
|
||||
|
||||
import com.shuwen.groot.api.dto.request.DeleteMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UpdateMaterialRequest;
|
||||
import com.shuwen.groot.api.dto.request.UploadMaterialRequest;
|
||||
import com.shuwen.groot.service.IMaterialService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:53
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/material/v1")
|
||||
public class MaterialController {
|
||||
|
||||
@Resource
|
||||
private IMaterialService materialService;
|
||||
|
||||
@RequestMapping(value = "/upload", produces = "application/json", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Object upload(@RequestBody UploadMaterialRequest request) {
|
||||
return materialService.upload(request);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/update", produces = "application/json", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Object update(@RequestBody UpdateMaterialRequest request) {
|
||||
return materialService.update(request);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/delete", produces = "application/json", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Object delete(@RequestBody DeleteMaterialRequest request) {
|
||||
return materialService.delete(request);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get", produces = "application/json", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Object get(@RequestParam(value = "id") String id,
|
||||
@RequestParam(value = "graph") String graph,
|
||||
@RequestParam(value = "convertUrl", defaultValue = "true", required = false) boolean convertUrl,
|
||||
@RequestParam(value = "signUrl", defaultValue = "true", required = false) boolean signUrl) {
|
||||
return materialService.get(id, graph, convertUrl, signUrl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.shuwen.groot.controller.log;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.shuwen.groot.api.dto.AbstractRequest;
|
||||
import com.shuwen.groot.api.dto.Response;
|
||||
import com.shuwen.groot.common.enums.InternalErrorCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Project: groot-material
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2022/12/2 16:50
|
||||
*/
|
||||
@Slf4j(topic = "access")
|
||||
public class AccessLogContext {
|
||||
|
||||
public static void log(String path, Map<String, Object> params, Map<String, Object> headers, AbstractRequest request,
|
||||
Response<?> response, long start) {
|
||||
JSONObject json = build(path, params, headers, request, response, start);
|
||||
json.put("code", InternalErrorCode.SUCCESS);
|
||||
log.info(json.toJSONString());
|
||||
}
|
||||
|
||||
public static void log(String path, Map<String, Object> params, Map<String, Object> headers, AbstractRequest request,
|
||||
Response<?> response, InternalErrorCode code, Exception e, long start) {
|
||||
JSONObject json = build(path, params, headers, request, response, start);
|
||||
json.put("code", code);
|
||||
json.put("message", ExceptionUtils.getStackTrace(e));
|
||||
log.info(json.toJSONString());
|
||||
}
|
||||
|
||||
public static void log(String path, Map<String, Object> params, Map<String, Object> headers, AbstractRequest request,
|
||||
Response<?> response, InternalErrorCode code, String message, long start) {
|
||||
JSONObject json = build(path, params, headers, request, response, start);
|
||||
json.put("code", code);
|
||||
json.put("message", message);
|
||||
log.info(json.toJSONString());
|
||||
}
|
||||
|
||||
private static JSONObject build(String path, Map<String, Object> params, Map<String, Object> headers, AbstractRequest request,
|
||||
Response<?> response, long start) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("requestId", response.getRequestId());
|
||||
json.put("appId", request != null ? request.getAppId() : null);
|
||||
json.put("userId", request != null ? request.getUserId() : null);
|
||||
json.put("path", path);
|
||||
json.put("params", params);
|
||||
json.put("headers", headers);
|
||||
json.put("request", request);
|
||||
json.put("response", response);
|
||||
json.put("cost", System.currentTimeMillis() - start);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.shuwen.groot.controller.status;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Created on 2020/4/9
|
||||
*
|
||||
* @author Kenn
|
||||
*/
|
||||
@RestController
|
||||
public class StatusController {
|
||||
|
||||
@GetMapping("/ok")
|
||||
public String ok() {
|
||||
return "ok";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
logging:
|
||||
file:
|
||||
path: /Users/Kenn/Documents/logs/groot-meta
|
||||
@@ -0,0 +1,3 @@
|
||||
logging:
|
||||
file:
|
||||
path: /home/admin/logs
|
||||
43
groot-data-bank-web/src/main/resources/application.yml
Normal file
43
groot-data-bank-web/src/main/resources/application.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: @activatedProperties@
|
||||
output:
|
||||
ansi.enabled: detect
|
||||
jackson:
|
||||
default-property-inclusion: non_null
|
||||
mapper:
|
||||
ACCEPT_CASE_INSENSITIVE_ENUMS: true
|
||||
deserialization:
|
||||
READ_UNKNOWN_ENUM_VALUES_AS_NULL: true
|
||||
groovy:
|
||||
template:
|
||||
check-template-location: false
|
||||
config:
|
||||
use-legacy-processing: true
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
management:
|
||||
endpoint:
|
||||
metrics.enabled: true
|
||||
prometheus.enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure.include: "*"
|
||||
base-path: /
|
||||
path-mapping:
|
||||
prometheus: /prometheus
|
||||
enabled-by-default: false
|
||||
metrics:
|
||||
export.prometheus.enabled: true
|
||||
dubbo:
|
||||
application:
|
||||
id: nft-platform
|
||||
name: nft-platform
|
||||
protocol:
|
||||
id: dubbo
|
||||
name: dubbo
|
||||
port: 7078
|
||||
registry:
|
||||
protocol: zookeeper
|
||||
logging:
|
||||
config: classpath:logback-spring.xml
|
||||
103
groot-data-bank-web/src/main/resources/logback-spring.xml
Normal file
103
groot-data-bank-web/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="true">
|
||||
<!-- 参考SpringBoot默认的logback配置,增加了error日志文件 -->
|
||||
<!-- org/springframework/boot/logging/logback/base.xml -->
|
||||
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
||||
|
||||
<property name="LOG_PATH" value="${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}"/>
|
||||
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
|
||||
<!-- 控制台日志 -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="infoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/info.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %c{1} %L [%p] %m%n %caller{0}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/info.log.%d{yyyy-MM-dd}</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/error.log</file>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %c{1} %L [%p] %m%n %caller{0}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/error.log.%d{yyyy-MM-dd}</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<appender name="debugFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/debug.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %c{1} %L [%p] %m%n %caller{0}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>DEBUG</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/debug.log.%d{yyyy-MM-dd}</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<logger name="com.shuwen.groot" additivity="true">
|
||||
<appender-ref ref="debugFile"/>
|
||||
<appender-ref ref="infoFile"/>
|
||||
<appender-ref ref="errorFile"/>
|
||||
</logger>
|
||||
|
||||
<appender name="accessFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/access.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%m%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/access.log.%d{yyyy-MM-dd}</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<logger name="access" level="INFO" additivity="true">
|
||||
<appender-ref ref="accessFile"/>
|
||||
</logger>
|
||||
|
||||
<!-- CONSOLE日志开关 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 9999
|
||||
dubbo:
|
||||
registry:
|
||||
address: 116.62.230.200:2181,116.62.225.137:2181,116.62.227.195:2181
|
||||
service:
|
||||
search:
|
||||
version: 2.0
|
||||
group: xhzy_es_test
|
||||
oss:
|
||||
endpoint: oss-cn-hangzhou.aliyuncs.com
|
||||
bucket: xhzy-test
|
||||
ossUrl: https://xhzy-test.oss-cn-hangzhou.aliyuncs.com
|
||||
prefix: groot-material
|
||||
media:
|
||||
utils:
|
||||
url: http://test.thumb-image.shuwen.com
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.shuwen.groot;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
/**
|
||||
* Project: groot-meta
|
||||
* Description:
|
||||
* Author: Kenn
|
||||
* Create: 2020/04/10 09:36
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@SpringBootTest(classes = Application.class)
|
||||
@AutoConfigureMockMvc
|
||||
public abstract class TestApplication {
|
||||
|
||||
protected static String MEDIA_TYPE = "application/json;charset=utf-8";
|
||||
|
||||
@Autowired
|
||||
protected MockMvc mockMvc;
|
||||
|
||||
protected MockHttpSession session;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
session = new MockHttpSession();
|
||||
}
|
||||
}
|
||||
297
pom.xml
Normal file
297
pom.xml
Normal file
@@ -0,0 +1,297 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.6</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>groot-data-bank-api</module>
|
||||
<module>groot-data-bank-common</module>
|
||||
<module>groot-data-bank-service</module>
|
||||
<module>groot-data-bank-manager</module>
|
||||
<module>groot-data-bank-web</module>
|
||||
</modules>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>private-releases</id>
|
||||
<name>maven-releases</name>
|
||||
<url>https://mvn.ops.xinhuazhiyun.com/repository/maven-releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>private-snapshots</id>
|
||||
<name>maven-snapshots</name>
|
||||
<url>https://mvn.ops.xinhuazhiyun.com/repository/maven-snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
|
||||
<aliyun.oss.version>3.15.2</aliyun.oss.version>
|
||||
|
||||
<dubbo.version>2.7.17</dubbo.version>
|
||||
<curator.version>4.2.0</curator.version>
|
||||
<zookeeper.version>3.4.14</zookeeper.version>
|
||||
|
||||
<lombok.version>1.18.24</lombok.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<commons.io.version>2.6</commons.io.version>
|
||||
<commons.pool2.version>2.11.1</commons.pool2.version>
|
||||
<commons.lang3.version>3.12.0</commons.lang3.version>
|
||||
<commons.collections4.version>4.4</commons.collections4.version>
|
||||
<commons.codec.version>1.15</commons.codec.version>
|
||||
<guava.version>31.1-jre</guava.version>
|
||||
<kotlin.version>1.5.21</kotlin.version>
|
||||
<log4j2.version>2.19.0</log4j2.version>
|
||||
<mockito.version>4.8.0</mockito.version>
|
||||
|
||||
<shuwen.configmap.version>1.0.7</shuwen.configmap.version>
|
||||
<shuwen.search.version>1.1.10-SNAPSHOT</shuwen.search.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- project start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-service</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.groot</groupId>
|
||||
<artifactId>groot-data-bank-manager</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- project end -->
|
||||
|
||||
<!-- xhzy start -->
|
||||
<dependency>
|
||||
<groupId>com.shuwen.ops</groupId>
|
||||
<artifactId>shaman-configmap</artifactId>
|
||||
<version>${shuwen.configmap.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.kubernetes</groupId>
|
||||
<artifactId>client-java-api</artifactId>
|
||||
<version>1.0.0-xhzy-3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.shuwen.search</groupId>
|
||||
<artifactId>search-proxy-api</artifactId>
|
||||
<version>${shuwen.search.version}</version>
|
||||
</dependency>
|
||||
<!-- xhzy end -->
|
||||
|
||||
<!-- aliyun start -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
<!-- aliyun end -->
|
||||
|
||||
<!-- service start -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
<version>${curator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-recipes</artifactId>
|
||||
<version>${curator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-client</artifactId>
|
||||
<version>${curator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<version>${zookeeper.version}</version>
|
||||
</dependency>
|
||||
<!-- service end -->
|
||||
|
||||
<!-- log4j start -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<!-- log4j end -->
|
||||
|
||||
<!-- tools start -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<version>${commons.pool2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons.collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons.codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-common</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.leopard</groupId>
|
||||
<artifactId>javahost</artifactId>
|
||||
<version>0.9.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.32</version>
|
||||
</dependency>
|
||||
<!-- tools end -->
|
||||
|
||||
<!-- test start -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>1.12.10</version>
|
||||
</dependency>
|
||||
<!-- test end -->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
Reference in New Issue
Block a user