Browse Source

feat: REPORT-70565 设计器环境监测(jar包异常、finedb、杀毒软件)

修改核心逻辑。
遇到不明确的异常, 则将异常添加进来后,进行匹配检测
遇到明确的异常,通过 DetectorType 进行匹配处理
统一检测时,直接调用
feature/x
Harrison 2 years ago
parent
commit
c966076300
  1. 17
      designer-base/src/main/java/com/fr/env/detect/base/CatchExceptionDetector.java
  2. 48
      designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java
  3. 15
      designer-base/src/main/java/com/fr/env/detect/base/DetectorManager.java
  4. 2
      designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java
  5. 77
      designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java
  6. 17
      designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java
  7. 36
      designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java
  8. 30
      designer-base/src/main/java/com/fr/env/detect/bean/ExceptionLog.java
  9. 15
      designer-base/src/main/java/com/fr/env/detect/bean/Message.java
  10. 6
      designer-base/src/main/java/com/fr/env/detect/impl/FineDbDirtyDetector.java
  11. 16
      designer-base/src/main/java/com/fr/env/detect/impl/FineDbLockedDetector.java
  12. 15
      designer-base/src/main/java/com/fr/env/detect/impl/FineDbPermissionDetector.java
  13. 15
      designer-base/src/main/java/com/fr/env/detect/impl/JarConflictDetector.java
  14. 51
      designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java
  15. 25
      designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java
  16. 1
      designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java
  17. 16
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java
  18. 13
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java
  19. 6
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java
  20. 595
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java

17
designer-base/src/main/java/com/fr/env/detect/base/CatchExceptionDetector.java vendored

@ -16,8 +16,14 @@ public abstract class CatchExceptionDetector extends AbstractExceptionDetector {
private ThrowableConverter throwableConverter;
public CatchExceptionDetector(DetectorType key, ThrowableStore throwableStore, ThrowableConverter throwableConverter) {
super(key);
public CatchExceptionDetector(DetectorType type, ThrowableConverter throwableConverter) {
super(type);
this.throwableStore = ThrowableStore.getInstance();
this.throwableConverter = throwableConverter;
}
public CatchExceptionDetector(DetectorType type, ThrowableStore throwableStore, ThrowableConverter throwableConverter) {
super(type);
this.throwableStore = throwableStore;
this.throwableConverter = throwableConverter;
}
@ -36,7 +42,12 @@ public abstract class CatchExceptionDetector extends AbstractExceptionDetector {
List<Throwable> throwableList = throwableStore.getAll();
for (Throwable throwable : throwableList) {
if (throwableConverter.accept(throwable)) {
return throwableConverter.convert(throwable);
DetectorResult result = throwableConverter.convert(throwable);
if (result == null) {
result = DetectorResult.normal(type());
}
return result;
}
}
return null;

48
designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java vendored

@ -2,14 +2,14 @@ package com.fr.env.detect.base;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.impl.HsqlDirtyDetector;
import com.fr.env.detect.impl.FineDbDirtyDetector;
import com.fr.env.detect.impl.FineDbLockedDetector;
import com.fr.env.detect.impl.FineDbPermissionDetector;
import com.fr.env.detect.impl.JarConflictDetector;
import com.fr.env.detect.impl.JarInconsistentDetector;
import com.fr.env.detect.impl.JarLackDetector;
import com.fr.env.detect.impl.converter.ClassConfictConvertor;
import com.fr.env.detect.impl.converter.FineDbDirtyConverter;
import com.fr.env.detect.impl.converter.FineDbLockedConverter;
import com.fr.env.detect.impl.converter.FineDbPermissionConverter;
import com.fr.env.detect.thowable.ThrowableLogAppender;
import com.fr.env.detect.thowable.ThrowableStore;
import com.fr.value.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
@ -32,28 +32,20 @@ public class DetectorBridge {
private static final DetectorBridge INSTANCE = new DetectorBridge();
}
private final NotNullLazyValue<ThrowableBridge> throwableBridge = new NotNullLazyValue<ThrowableBridge>() {
@Override
protected @NotNull ThrowableBridge compute() {
ThrowableBridge bridge = new ThrowableBridge();
bridge.register(new ClassConfictConvertor());
bridge.register(new FineDbDirtyConverter());
bridge.register(new FineDbLockedConverter());
bridge.register(new FineDbPermissionConverter());
return bridge;
}
};
private final NotNullLazyValue<DetectorManager> detectorManager = new NotNullLazyValue<DetectorManager>() {
@Override
protected @NotNull DetectorManager compute() {
DetectorManager manager = new DetectorManager();
manager.register(new HsqlDirtyDetector());
manager.register(new FineDbDirtyDetector());
manager.register(new FineDbPermissionDetector());
manager.register(new FineDbLockedDetector());
manager.register(new JarInconsistentDetector());
manager.register(new JarLackDetector());
manager.register(new JarConflictDetector());
return manager;
}
};
@ -90,7 +82,8 @@ public class DetectorBridge {
}
/**
* 执行-检测异常
* 异常检测
* 对异常统一检测
*
* @return 能够检测出的异常情况
*/
@ -100,13 +93,22 @@ public class DetectorBridge {
}
/**
* 执行-捕获异常
* 异常检测
* 当遇到异常时且异常难以处理直接导致服务器启动失败时调用
* 将异常添加进来统一检测
*
* @param throwable 异常
* @return 检测结果
*/
public Optional<DetectorResult> convert(Throwable throwable) {
public Stream<DetectorResult> detect(Throwable throwable) {
// 先清理一下
ThrowableStore.getInstance().reset();
ThrowableStore.getInstance().add(throwable);
Stream<DetectorResult> result = detect();
ThrowableStore.getInstance().reset();
return throwableBridge.getValue().convert(throwable);
return result;
}
}

15
designer-base/src/main/java/com/fr/env/detect/base/DetectorManager.java vendored

@ -1,7 +1,7 @@
package com.fr.env.detect.base;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import java.util.ArrayList;
import java.util.List;
@ -25,16 +25,25 @@ class DetectorManager {
public Stream<DetectorResult> detect() {
return detectors.stream()
Stream<DetectorResult> results = detectors.stream()
.map(ExceptionDetector::detect)
.filter(Objects::nonNull);
// 记录一下日志
results.forEach(DetectorResult::log);
return results;
}
public Optional<DetectorResult> detect(DetectorType type) {
return detectors.stream()
Optional<DetectorResult> result = detectors.stream()
.filter((detector -> type == detector.type()))
.findFirst()
.map(ExceptionDetector::detect);
// 记录日志
result.ifPresent(DetectorResult::log);
return result;
}
}

2
designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java vendored

@ -2,7 +2,6 @@ package com.fr.env.detect.base;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import org.jetbrains.annotations.Nullable;
/**
* created by Harrison on 2022/05/13
@ -21,7 +20,6 @@ public interface ExceptionDetector {
*
* @return 结果
*/
@Nullable
DetectorResult detect();
}

77
designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java vendored

@ -1,7 +1,5 @@
package com.fr.env.detect.bean;
import org.jetbrains.annotations.Nullable;
/**
* 检测结果
*
@ -11,42 +9,76 @@ public class DetectorResult {
private DetectorType type;
private DetectorStatus status;
private ExceptionTips tips;
private ExceptionSolution solution;
public DetectorResult(DetectorType type, ExceptionTips tips, ExceptionSolution solution) {
private ExceptionLog log;
private DetectorResult(DetectorType type) {
this.type = type;
}
private DetectorResult(DetectorType type, ExceptionTips tips, ExceptionSolution solution, ExceptionLog log) {
this.type = type;
this.tips = tips;
this.solution = solution;
this.log = log;
}
public static DetectorResult normal(DetectorType type) {
DetectorResult result = new DetectorResult(type);
result.status = DetectorStatus.NORMAL;
return result;
}
public static DetectorResult exception(DetectorType type, ExceptionTips tips, ExceptionSolution solution, ExceptionLog log) {
DetectorResult result = new DetectorResult(type, tips, solution, log);
result.status = DetectorStatus.EXCEPTION;
return result;
}
public DetectorStatus getStatus() {
return status;
}
public DetectorType getType() {
return type;
}
@Nullable
public ExceptionTips getTips() {
return tips;
}
@Nullable
public ExceptionSolution getSolution() {
return solution;
}
public static DetectorResultBuilder builder() {
public void log() {
return new DetectorResultBuilder();
if (log != null) {
log.log();
}
}
public static DetectorResultBuilder builder() {
return new DetectorResultBuilder()
.withStatus(DetectorStatus.EXCEPTION);
}
public static final class DetectorResultBuilder {
private DetectorType type;
private DetectorStatus status;
private ExceptionTips tips;
private ExceptionSolution solution;
private ExceptionLog log;
private DetectorResultBuilder() {
}
@ -56,6 +88,16 @@ public class DetectorResult {
return this;
}
public DetectorResultBuilder withStatus(DetectorStatus status) {
this.status = status;
return this;
}
public DetectorResultBuilder withTips(ExceptionTips tips) {
this.tips = tips;
return this;
}
public DetectorResultBuilder withTips(String message) {
Message.Simple simple = new Message.Simple(message);
@ -63,8 +105,8 @@ public class DetectorResult {
return this;
}
public DetectorResultBuilder withTips(ExceptionTips tips) {
this.tips = tips;
public DetectorResultBuilder withSolution(ExceptionSolution solution) {
this.solution = solution;
return this;
}
@ -75,14 +117,21 @@ public class DetectorResult {
return this;
}
public DetectorResultBuilder withSolution(ExceptionSolution solution) {
this.solution = solution;
public DetectorResultBuilder withLog(String log, Object... args) {
this.log = ExceptionLog.create(log, args);
return this;
}
public DetectorResult build() {
public DetectorResultBuilder withLog(ExceptionLog log) {
this.log = log;
return this;
}
return new DetectorResult(type, tips, solution);
public DetectorResult build() {
DetectorResult detectorResult = new DetectorResult(type, tips, solution, log);
detectorResult.status = this.status;
return detectorResult;
}
}
}

17
designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java vendored

@ -0,0 +1,17 @@
package com.fr.env.detect.bean;
/**
* created by Harrison on 2022/05/27
**/
public enum DetectorStatus {
/**
* 正常
*/
NORMAL,
/**
* 异常
*/
EXCEPTION,
}

36
designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java vendored

@ -1,5 +1,7 @@
package com.fr.env.detect.bean;
import com.fr.design.i18n.Toolkit;
/**
* 检测的原生数据
* 其实这里可以继续拆分到不同的逻辑下面的, 比如实际生成 DetectorResult 的地方 {@link com.fr.env.detect.base.ExceptionDetector}
@ -13,6 +15,7 @@ public enum DetectorType {
* 缺少 JAR
*/
LACK_OF_JAR(Kind.JAR, WorkType.LOCAL,
"Fine_Design_Basic_Jar_Lacked_Desc",
"Fine_Design_Basic_Jar_Lack",
"Fine_Design_Basic_Jar_Solution",
"Fine_Design_Basic_Log_Jar_Lack"),
@ -22,6 +25,7 @@ public enum DetectorType {
* JAR 包版本不一致
*/
JAR_IN_CONSISTENCE(Kind.JAR, WorkType.SIMPLE,
"Fine_Design_Basic_Jar_InConsistent_Desc",
"Fine_Design_Basic_Jar_InConsistent",
"Fine_Design_Basic_Jar_Solution",
"Fine_Design_Basic_Log_Jar_InConsistent"),
@ -30,6 +34,7 @@ public enum DetectorType {
* JAR 包冲突
*/
JAR_CONFLICT(Kind.JAR, WorkType.REMOTE,
"Fine_Design_Basic_Jar_Problem_Desc",
"Fine_Design_Basic_Jar_Problem",
"Fine_Design_Basic_Jar_Solution",
"Fine_Design_Basic_Log_Jar_Problem"),
@ -38,6 +43,7 @@ public enum DetectorType {
* FineDB 权限问题
*/
FINE_DB_PERMISSION(Kind.FINE_DB, WorkType.LOCAL,
"Fine_Design_Basic_FineDB_Permission_Occupied_Desc",
"Fine_Design_Basic_FineDB_Permission_Occupied",
"Fine_Design_Basic_FineDB_Solution",
"Fine_Design_Basic_Log_FineDB_Permission_Occupied"),
@ -46,6 +52,7 @@ public enum DetectorType {
* FineDB
*/
FINE_DB_LOCKED(Kind.FINE_DB, WorkType.LOCAL,
"Fine_Design_Basic_FineDB_Locked_Desc",
"Fine_Design_Basic_FineDB_Locked",
"Fine_Design_Basic_FineDB_Solution",
"Fine_Design_Basic_Log_FineDB_Locked"),
@ -54,6 +61,7 @@ public enum DetectorType {
* FineDB 脏数据
*/
FINE_DB_DIRTY(Kind.FINE_DB, WorkType.SIMPLE,
"Fine_Design_Basic_FineDB_Dirty_Data_Desc",
"Fine_Design_Basic_FineDB_Dirty_Data",
"Fine_Design_Basic_FineDB_Dirty_Solution",
"Fine_Design_Basic_Log_FineDB_Dirty_Data")
@ -63,21 +71,32 @@ public enum DetectorType {
private final WorkType workType;
private final String descLocale;
private final String tipsLocale;
private final String solutionLocale;
private final String logLocale;
DetectorType(Kind kind, WorkType workType, String tipsLocale, String solutionLocale, String logLocale) {
DetectorType(Kind kind, WorkType workType, String descLocale, String tipsLocale, String solutionLocale, String logLocale) {
this.kind = kind;
this.workType = workType;
this.descLocale = descLocale;
this.tipsLocale = tipsLocale;
this.solutionLocale = solutionLocale;
this.logLocale = logLocale;
}
public String getDescription() {
return Toolkit.i18nText(descLocale);
}
public String getDescLocale() {
return descLocale;
}
public Kind getKind() {
return kind;
}
@ -103,11 +122,22 @@ public enum DetectorType {
/**
* JAR 类型
*/
JAR,
JAR("Fine_Design_Basic_Jar_Kind_Desc"),
/**
* FineDB 类型
*/
FINE_DB
FINE_DB("Fine_Design_Basic_FineDB_Kind_Desc");
private final String locale;
Kind(String locale) {
this.locale = locale;
}
public String getDescription() {
return Toolkit.i18nText(this.locale);
}
}
public enum WorkType {

30
designer-base/src/main/java/com/fr/env/detect/bean/ExceptionLog.java vendored

@ -1,24 +1,36 @@
package com.fr.env.detect.bean;
import com.fr.log.FineLoggerFactory;
/**
* created by Harrison on 2022/05/13
**/
public class ExceptionLog {
private final String errorCode;
private final String template;
private final Object[] args;
private ExceptionLog(String template, Object... args) {
this.template = template;
this.args = args;
}
public static ExceptionLog create(String template, Object... args) {
return new ExceptionLog(template, args);
}
private final String locale;
public void log() {
public ExceptionLog(String errorCode, String locale) {
this.errorCode = errorCode;
this.locale = locale;
FineLoggerFactory.getLogger().error(template, args);
}
public String getErrorCode() {
return errorCode;
public String getTemplate() {
return template;
}
public String getLocale() {
return locale;
public Object[] getArgs() {
return args;
}
}

15
designer-base/src/main/java/com/fr/env/detect/bean/Message.java vendored

@ -12,6 +12,13 @@ public interface Message {
*/
Type getType();
/**
* 返回内容
*
* @return 内容
*/
String get();
enum Type {
/**
@ -33,7 +40,8 @@ public interface Message {
this.message = message;
}
public String getMessage() {
@Override
public String get() {
return message;
}
@ -54,6 +62,11 @@ public interface Message {
this.link = link;
}
@Override
public String get() {
return getText();
}
public String getText() {
return text;
}

6
designer-base/src/main/java/com/fr/env/detect/impl/HsqlDirtyDetector.java → designer-base/src/main/java/com/fr/env/detect/impl/FineDbDirtyDetector.java vendored

@ -8,13 +8,13 @@ import com.fr.env.detect.thowable.ThrowableStore;
/**
* created by Harrison on 2022/05/25
**/
public class HsqlDirtyDetector extends CatchExceptionDetector {
public class FineDbDirtyDetector extends CatchExceptionDetector {
public HsqlDirtyDetector() {
public FineDbDirtyDetector() {
this(ThrowableStore.getInstance());
}
public HsqlDirtyDetector(ThrowableStore throwableStore) {
public FineDbDirtyDetector(ThrowableStore throwableStore) {
super(DetectorType.FINE_DB_DIRTY, throwableStore, new FineDbDirtyConverter());
}

16
designer-base/src/main/java/com/fr/env/detect/impl/FineDbLockedDetector.java vendored

@ -0,0 +1,16 @@
package com.fr.env.detect.impl;
import com.fr.env.detect.base.CatchExceptionDetector;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.impl.converter.FineDbLockedConverter;
/**
* created by Harrison on 2022/05/26
**/
public class FineDbLockedDetector extends CatchExceptionDetector {
public FineDbLockedDetector() {
super(DetectorType.FINE_DB_LOCKED, new FineDbLockedConverter());
}
}

15
designer-base/src/main/java/com/fr/env/detect/impl/FineDbPermissionDetector.java vendored

@ -0,0 +1,15 @@
package com.fr.env.detect.impl;
import com.fr.env.detect.base.CatchExceptionDetector;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.impl.converter.FineDbPermissionConverter;
/**
* created by Harrison on 2022/05/26
**/
public class FineDbPermissionDetector extends CatchExceptionDetector {
public FineDbPermissionDetector() {
super(DetectorType.FINE_DB_PERMISSION, new FineDbPermissionConverter());
}
}

15
designer-base/src/main/java/com/fr/env/detect/impl/JarConflictDetector.java vendored

@ -0,0 +1,15 @@
package com.fr.env.detect.impl;
import com.fr.env.detect.base.CatchExceptionDetector;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.impl.converter.ClassConfictConvertor;
/**
* created by Harrison on 2022/05/26
**/
public class JarConflictDetector extends CatchExceptionDetector {
public JarConflictDetector() {
super(DetectorType.JAR_CONFLICT, new ClassConfictConvertor());
}
}

51
designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java vendored

@ -7,15 +7,14 @@ import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionLog;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.exception.DetectorException;
import com.fr.general.build.BuildInfo;
import com.fr.general.build.BuildInfoManager;
import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.log.FineLoggerFactory;
import com.fr.third.guava.collect.MapDifference;
import com.fr.third.guava.collect.Maps;
import com.fr.third.org.apache.commons.lang3.StringUtils;
@ -24,6 +23,7 @@ import com.fr.workspace.WorkContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -37,42 +37,57 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
super(DetectorType.JAR_IN_CONSISTENCE);
}
/**
* 本地
* 先获取 Designer, 然后对其他的 JAR 信息匹配
* <p>
* 远程
* 两边一一对应匹配
*
* @return 结果
*/
@Override
public DetectorResult detect() {
DetectorResult.DetectorResultBuilder builder = DetectorResult.builder();
if (WorkContext.getCurrent().isLocal()) {
// 本地的获取方式
BuildInfoOperator operator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = operator.getBuildInfos();
String designerBuild = buildInfos.stream()
// 获取设计器的 build
Optional<String> designerBuild = buildInfos.stream()
.filter(DetectorUtil::isDesignerJar)
.map(BuildInfo::getGroupBuild)
.filter(StringUtils::isNotEmpty)
.findFirst()
.orElseThrow(DetectorException::new);
.findFirst();
// 如果 build
if (!designerBuild.isPresent()) {
return DetectorResult.normal(type());
}
// 获取所有的不一致的 build
List<BuildInfo> inConsistentInfos = buildInfos.stream()
.filter((e) -> !StringUtils.equals(designerBuild, e.getGroupBuild()))
.filter((e) -> !StringUtils.equals(designerBuild.get(), e.getGroupBuild()))
.collect(Collectors.toList());
// 没有直接返回
if (Collections.isEmpty(inConsistentInfos)) {
return null;
return DetectorResult.normal(type());
}
// 有的话
List<String> inConsistentJars = inConsistentInfos.stream()
.map(BuildInfo::getJar)
.collect(Collectors.toList());
String message = StringUtils.join(",", inConsistentJars);
String tipsMessage = Toolkit.i18nText("Fine_Design_Basic_Detect_Local") + Toolkit.i18nText(type().getTipsLocale()) + "\n" + message;
builder.withTips(new ExceptionTips(new Message.Simple(tipsMessage)))
.withSolution(new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null));
FineLoggerFactory.getLogger().error(type().getLogLocale() + message);
return DetectorResult.exception(type(),
new ExceptionTips(new Message.Simple(tipsMessage)),
new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null),
ExceptionLog.create(type().getLogLocale() + message));
} else {
@ -91,20 +106,20 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
Map<String, String> diffInCommon = difference.entriesInCommon();
if (diffInCommon.isEmpty()) {
return null;
return DetectorResult.normal(type());
}
Set<String> inConsistentJars = diffInCommon.keySet();
String message = StringUtils.join(",", inConsistentJars);
Message.Simple tipsMessage = new Message.Simple(Toolkit.i18nText("Fine_Design_Basic_Detect_Server") + Toolkit.i18nText(type().getTipsLocale()) + "\n" + message);
builder.withTips(new ExceptionTips(tipsMessage))
.withSolution(new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null));
return DetectorResult.exception(type(),
new ExceptionTips(tipsMessage),
new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null),
ExceptionLog.create(type().getLogLocale() + message));
}
return builder.build();
}
private Map<String, String> groupBy(List<BuildInfo> localInfos) {

25
designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java vendored

@ -7,6 +7,7 @@ import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionLog;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
@ -14,7 +15,6 @@ import com.fr.general.build.BuildInfo;
import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CommonUtils;
import com.fr.stable.StableUtils;
import com.fr.third.guava.collect.Lists;
@ -43,11 +43,9 @@ public class JarLackDetector extends AbstractExceptionDetector {
// 不支持远程
if (!WorkContext.getCurrent().isLocal()) {
return null;
return DetectorResult.normal(type());
}
DetectorResult.DetectorResultBuilder builder = DetectorResult.builder();
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
@ -56,28 +54,25 @@ public class JarLackDetector extends AbstractExceptionDetector {
.collect(Collectors.toList());
if (Collections.isEmpty(lackInfos)) {
return null;
return DetectorResult.normal(type());
}
Message message = tipsMessage(lackInfos);
builder.withTips(new ExceptionTips(message))
.withSolution(
Message tipsMsg = tipsMessage(lackInfos);
ExceptionLog exceptionLog = exceptionLog(lackInfos);
return DetectorResult.exception(type(), new ExceptionTips(tipsMsg),
new ExceptionSolution(
new Message.Link(InterProviderFactory.getProvider().getLocText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK),
null));
logException(lackInfos);
return builder.build();
null), exceptionLog);
}
private void logException(List<BuildInfo> lackInfos) {
private ExceptionLog exceptionLog(List<BuildInfo> lackInfos) {
List<String> jarInfos = lackInfos.stream()
.map(BuildInfo::getJar)
.collect(Collectors.toList());
String message = StringUtils.join(",", jarInfos);
FineLoggerFactory.getLogger().error(type().getLogLocale() + message);
return ExceptionLog.create(type().getLogLocale() + message);
}
private boolean isLackInfo(BuildInfo e) {

1
designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java vendored

@ -93,6 +93,7 @@ public class ClassConfictConvertor implements ThrowableConverter {
}
}
}
} catch (IOException ignore) {
}
}

16
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java vendored

@ -10,7 +10,6 @@ import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.env.detect.thowable.ThrowableConverter;
import com.fr.log.FineLoggerFactory;
import com.fr.third.org.hibernate.exception.GenericJDBCException;
import org.jetbrains.annotations.Nullable;
@ -19,6 +18,8 @@ import java.util.Iterator;
import java.util.Map;
/**
* 脏数据检测
*
* created by Harrison on 2022/05/25
**/
public class FineDbDirtyConverter implements ThrowableConverter {
@ -36,6 +37,14 @@ public class FineDbDirtyConverter implements ThrowableConverter {
return false;
}
/**
* 根据堆栈确认是否是从配置中发出来的异常
* 如果是则找到对应的配置的表
* 输出信息
*
* @param throwable 异常
* @return 检测结果
*/
@Override
public @Nullable DetectorResult convert(Throwable throwable) {
@ -72,10 +81,9 @@ public class FineDbDirtyConverter implements ThrowableConverter {
}
});
builder.withTips(tipsLocale)
.withSolution(exceptionSolution);
.withSolution(exceptionSolution)
.withLog(Toolkit.i18nText(detectorType.getLogLocale(), tableName));
String errorMsg = Toolkit.i18nText(detectorType.getLogLocale(), tableName);
FineLoggerFactory.getLogger().error(errorMsg);
return builder.build();
}
}

13
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java vendored

@ -25,6 +25,12 @@ public class FineDbLockedConverter implements ThrowableConverter {
return false;
}
/**
* 检测 FineDB 是否锁住
*
* @param throwable 异常
* @return 结果
*/
@Override
public DetectorResult convert(Throwable throwable) {
@ -33,15 +39,16 @@ public class FineDbLockedConverter implements ThrowableConverter {
sign = sign.getCause();
}
DetectorType type = DetectorType.FINE_DB_LOCKED;
String message = sign.getMessage();
if (message.contains("lock")) {
DetectorType type = DetectorType.FINE_DB_LOCKED;
String tipsLocale = type.getTipsLocale();
return DetectorResult.builder()
.withType(type)
.withTips(Toolkit.i18nText(tipsLocale))
.withTips(Toolkit.i18nText(type.getTipsLocale()))
.withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK)
.withLog(Toolkit.i18nText(type.getLogLocale()))
.build();
}
return null;

6
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java vendored

@ -35,15 +35,15 @@ public class FineDbPermissionConverter implements ThrowableConverter {
sign = sign.getCause();
}
DetectorType type = DetectorType.FINE_DB_PERMISSION;
String message = sign.getMessage();
if (message.contains("permission")) {
DetectorType type = DetectorType.FINE_DB_PERMISSION;
String tipsLocale = type.getTipsLocale();
return DetectorResult.builder()
.withType(type)
.withTips(Toolkit.i18nText(tipsLocale))
.withTips(Toolkit.i18nText(type.getTipsLocale()))
.withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK)
.withLog(type.getLogLocale())
.build();
}
return null;

595
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java vendored

@ -0,0 +1,595 @@
package com.fr.env.detect.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.components.notification.NotificationAction;
import com.fr.design.components.notification.NotificationDialog;
import com.fr.design.components.notification.NotificationDialogProperties;
import com.fr.design.components.notification.NotificationMessage;
import com.fr.design.components.notification.NotificationModel;
import com.fr.design.components.notification.NotificationType;
import com.fr.design.components.table.TablePanel;
import com.fr.design.constants.DesignerColor;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonUI;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.env.detect.base.DetectorBridge;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorStatus;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.third.guava.collect.Lists;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.plaf.ButtonUI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* created by Harrison on 2022/05/26
**/
public class EnvDetectorDialog extends JDialog {
private static final ImageIcon LOADING_ICON = getLoadingIcon();
private JPanel body;
private final JPanel headerPanel;
private final TablePanel tablePanel;
private final JPanel tailPanel;
/* 数据 model */
private EnvDetectorModel model = new EnvDetectorModel();
/* 流程 model */
/**
* 默认是第一个要检测
*/
private int currentDetectIndex = 0;
private EnvDetectorButtonStatus buttonStatus = EnvDetectorButtonStatus.START;
private SwingWorker<Void, Void> detectWorker = null;
public EnvDetectorDialog(Frame owner) {
super(owner);
configProperties();
this.body = FRGUIPaneFactory.createBorderLayout_L_Pane();
Color backgroundColor = new Color(240, 240, 243, 1);
this.body.setBackground( backgroundColor);
this.headerPanel = createHeaderPanel();
body.add(headerPanel, BorderLayout.NORTH);
this.tablePanel = createTablePanel();
body.add(tablePanel, BorderLayout.CENTER);
/* tailPanel*/
this.tailPanel = createTailPanel();
body.add(tailPanel, BorderLayout.SOUTH);
add(body);
Dimension preferredSize = body.getPreferredSize();
setSize(preferredSize);
repaint();
pack();
GUICoreUtils.centerWindow(this);
}
@NotNull
private JPanel createHeaderPanel() {
JPanel headerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
headerPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 12, 0));
UIButton detectButton = new UIButton(buttonStatus.getDesc()) {
@Override
public ButtonUI getUI() {
return new UIButtonUI() {
@Override
protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) {
if (isPressed(b) && b.isPressedPainted()) {
GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles),
DesignerColor.Button.Primary.PRESSED);
} else if (isRollOver(b)) {
GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(),
DesignerColor.Button.Primary.HOVER);
} else if (b.isNormalPainted()) {
GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(),
DesignerColor.Button.Primary.NORMAL);
}
}
};
}
};
detectButton.setForeground(Color.WHITE);
detectButton.addActionListener(event -> {
if (buttonStatus.isNotExecuting()) {
startDetecting(detectButton);
} else {
stopDetecting(detectButton);
}
});
detectButton.setPreferredSize(new Dimension(68, 20));
detectButton.setBorderPainted(false);
detectButton.setContentAreaFilled(false);
headerPanel.add(detectButton, BorderLayout.WEST);
return headerPanel;
}
private void startDetecting(UIButton detectButton) {
// 执行前
buttonStatus = buttonStatus.next();
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc()));
detectWorker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
List<EnvDetectorItem> items = model.getItems();
// 执行刷新
for (int i = currentDetectIndex; i < items.size(); i++) {
// 看一下是否关闭了, 有可能已经关闭了。
if (buttonStatus.isNotExecuting()) {
return null;
}
// 刷新一下面板-开始执行啦
UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refresh);
EnvDetectorItem item = items.get(i);
DetectorType type = item.getType();
// 执行检测, UI-当前在检测中
Optional<DetectorResult> detect = UIUtil.waitUntil(
() -> DetectorBridge.getInstance().detect(type),
1000, TimeUnit.MILLISECONDS);
// 获取结果,更新UI
detect.ifPresent(item::setResult);
// 只有还在运行中,才会真正的刷新面板
if (buttonStatus.isExecuting()) {
// 在刷新一下面板
UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refresh);
currentDetectIndex++;
}
}
return null;
}
@Override
protected void done() {
if (buttonStatus.isExecuting()) {
// 执行结束
buttonStatus = buttonStatus.next();
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc()));
}
}
};
// 开始执行
detectWorker.execute();
}
private void stopDetecting(UIButton detectButton) {
buttonStatus = buttonStatus.next();
// 先停止
detectWorker.cancel(false);
// 更改-UI
// 执行中
UIUtil.invokeLaterIfNeeded(() -> {
// 刷新按钮
detectButton.setText(buttonStatus.getDesc());
// 刷新面板
refresh();
});
}
@NotNull
private TablePanel createTablePanel() {
TablePanel tablePanel = new TablePanel(18, 3);
tablePanel.updateHeaders(new String[] {
Toolkit.i18nText("Fine-Design_Basic_Detect_Kind"),
Toolkit.i18nText("Fine-Design_Basic_Detect_Item"),
Toolkit.i18nText("Fine-Design_Basic_Detect_Result")});
updateTable(tablePanel);
return tablePanel;
}
private void updateTable(TablePanel tablePanel) {
Map<DetectorType.Kind, List<EnvDetectorItem>> itemMap = model.getItemMap();
// 行号, 这边更新是通过 行/列 。 不是索引
int row = 1;
for (Map.Entry<DetectorType.Kind, List<EnvDetectorItem>> entry : itemMap.entrySet()) {
DetectorType.Kind kind = entry.getKey();
List<EnvDetectorItem> items = entry.getValue();
for (int i = 0; i < items.size(); i++) {
if (i == 0) {
tablePanel.updateCell(row, 1, kind.getDescription());
}
EnvDetectorItem item = items.get(i);
tablePanel.updateCell(row, 2, new UILabel(item.getDescription()));
DetectorResult result = item.getResult();
int detectRow = currentDetectIndex + 1;
if (result == null) {
// 处于非正在检测状态 或者 索引不等于当前行号的时候
UILabel label;
if (buttonStatus.isExecuting() && detectRow == row) {
// 正在检测索引
label = new UILabel(LOADING_ICON, UILabel.LEADING);
} else {
label = new UILabel("-");
}
tablePanel.updateCell(row, 3, label);
} else {
Component resultComponent = createResultComponent(result);
tablePanel.updateCell(row, 3, resultComponent);
}
row++;
}
}
}
private static ImageIcon getLoadingIcon() {
URL resource = EnvDetectorDialog.class.getResource("/com/fr/design/standard/loading/loading-120.gif");
if (resource == null) {
return null;
}
ImageIcon loadingIcon = new ImageIcon(resource);
int width = 16;
int height = 16;
loadingIcon.setImage(loadingIcon.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
return loadingIcon;
}
private Component createResultComponent(DetectorResult result) {
JPanel statusPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
if (result.getStatus() == DetectorStatus.NORMAL) {
statusPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_success.svg")), BorderLayout.WEST);
statusPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Normal")), BorderLayout.CENTER);
} else {
statusPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_error.svg")), BorderLayout.WEST);
statusPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Exception")), BorderLayout.CENTER);
UILabel detailLabel = new UILabel(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(new Color(65, 155, 249));
detailLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
NotificationDialogProperties properties = new NotificationDialogProperties((Frame) EnvDetectorDialog.this.getOwner(), Toolkit.i18nText("Fine-Design_Basic_Detect_Notification_Title"));
Stream<DetectorResult> results = model.getResults();
List<NotificationModel> notificationModels = results
.filter(Objects::nonNull)
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.map(EnvDetectorDialog.this::convertDetectorResult)
.collect(Collectors.toList());
NotificationDialog dialog = new NotificationDialog(properties, notificationModels);
dialog.open();
}
});
statusPanel.add(detailLabel);
}
return statusPanel;
}
private NotificationModel convertDetectorResult(DetectorResult result) {
List<NotificationMessage> messages = new ArrayList<>();
Function<Message, Optional<NotificationMessage>> convert2NotificationMsg = message -> {
NotificationMessage notificationMessage = null;
if (message != null) {
Message.Type type = message.getType();
switch (type) {
case SIMPLE:
notificationMessage = (new NotificationMessage.SimpleMessage(message.get()));
break;
case LINK:
Message.Link linkMsg = (Message.Link) message;
notificationMessage = new NotificationMessage.LinkMessage(linkMsg.getText(), linkMsg.getLink());
break;
default:
break;
}
}
return Optional.ofNullable(notificationMessage);
};
ExceptionTips tips = result.getTips();
convert2NotificationMsg
.apply(tips.getMessage())
.ifPresent(messages::add);
ExceptionSolution solution = result.getSolution();
convert2NotificationMsg.apply(solution.getMessage())
.ifPresent(messages::add);
NotificationAction notificationAction = null;
SolutionAction solutionAction = solution.getAction();
if (solutionAction != null) {
notificationAction = new NotificationAction() {
@Override
public String name() {
return solutionAction.name();
}
@Override
public void run(Object... args) {
solutionAction.run();
}
};
}
return new NotificationModel(NotificationType.WARNING, notificationAction, messages);
}
private void refresh() {
updateTable(this.tablePanel);
pack();
repaint();
}
@NotNull
private JPanel createTailPanel() {
JPanel tailPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
tailPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
JPanel configPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
{
UICheckBox checkBox = new UICheckBox();
configPanel.add(checkBox, BorderLayout.WEST);
UILabel description = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Switch"));
configPanel.add(description, BorderLayout.EAST);
}
tailPanel.add(configPanel, BorderLayout.WEST);
JPanel actionsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
actionsPanel.setLayout(FRGUIPaneFactory.createM_BorderLayout());
{
UIButton confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm"));
confirmButton.addActionListener((e) -> {
setVisible(false);
dispose();
// 配置处理
// todo
});
actionsPanel.add(confirmButton, BorderLayout.WEST);
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel"));
cancelButton.addActionListener((e) -> {
setVisible(false);
dispose();
});
actionsPanel.add(cancelButton, BorderLayout.EAST);
}
tailPanel.add(actionsPanel, BorderLayout.EAST);
return tailPanel;
}
private void configProperties() {
setTitle(Toolkit.i18nText("Fine-Design_Basic_Detect_Title"));
setModal(false);
setFocusable(false);
setAutoRequestFocus(false);
setResizable(false);
}
/**
* 数据 model
*
* kind-list_item
*/
private class EnvDetectorModel {
private Map<DetectorType.Kind, List<EnvDetectorItem>> itemMap = new LinkedHashMap<>();
public EnvDetectorModel() {
itemMap.put(DetectorType.Kind.JAR, Lists.newArrayList(new EnvDetectorItem(DetectorType.LACK_OF_JAR), new EnvDetectorItem(DetectorType.JAR_IN_CONSISTENCE), new EnvDetectorItem(DetectorType.JAR_CONFLICT)));
itemMap.put(DetectorType.Kind.FINE_DB, Lists.newArrayList(new EnvDetectorItem(DetectorType.FINE_DB_LOCKED), new EnvDetectorItem(DetectorType.FINE_DB_PERMISSION), new EnvDetectorItem(DetectorType.FINE_DB_DIRTY)));
}
public void update(DetectorType type, DetectorResult result) {
List<EnvDetectorItem> items = itemMap.get(type.getKind());
items.stream()
.filter((e) -> e.getType() == type)
.findFirst()
.ifPresent((e) -> {e.setResult(result);});
}
public Stream<DetectorResult> getResults() {
return getItems().stream()
.map(EnvDetectorItem::getResult);
}
public List<EnvDetectorItem> getItems() {
return itemMap.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
public Map<DetectorType.Kind, List<EnvDetectorItem>> getItemMap() {
return this.itemMap;
}
}
private class EnvDetectorItem {
private DetectorType type;
private DetectorResult result;
public EnvDetectorItem(DetectorType detectorType) {
this.type = detectorType;
}
public DetectorType getType() {
return type;
}
public String getKind() {
return this.type.getKind().getDescription();
}
public String getDescription() {
return this.type.getDescription();
}
public DetectorResult getResult() {
return result;
}
public void setResult(DetectorResult result) {
this.result = result;
}
}
/**
* 按钮的当前状态
*/
private enum EnvDetectorButtonStatus {
/**
* 开始 -> 停止
*/
START("Fine-Design_Basic_Detect_Start") {
@Override
public EnvDetectorButtonStatus next() {
return STOP;
}
},
/**
* 停止 -> 继续
*/
STOP("Fine-Design_Basic_Detect_Stop") {
@Override
public EnvDetectorButtonStatus next() {
return CONTINUE;
}
},
/**
* 继续 -> 停止
*/
CONTINUE("Fine-Design_Basic_Detect_Continue") {
@Override
public EnvDetectorButtonStatus next() {
return STOP;
}
},
/**
* 重新 -> 停止
*/
A_NEW("Fine-Design_Basic_Detect_A_New") {
@Override
public EnvDetectorButtonStatus next() {
return STOP;
}
}
;
private String descLocale;
EnvDetectorButtonStatus(String descLocale) {
this.descLocale = descLocale;
}
public String getDesc() {
return Toolkit.i18nText(descLocale);
}
/**
* 在执行中
*
* @return /
*/
public boolean isExecuting() {
return this == EnvDetectorButtonStatus.STOP;
};
/**
* 不在执行中
*
* @return /
*/
public boolean isNotExecuting() {
return !isExecuting();
}
public abstract EnvDetectorButtonStatus next();
}
}
Loading…
Cancel
Save