cn.keepbx.jpom.RemoteVersion Maven / Gradle / Ivy
package cn.keepbx.jpom;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.*;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.system.SystemUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.util.concurrent.TimeUnit;
/**
* 远程的版本信息
*
*
* {
* "tag_name": "v2.6.4",
* "agentUrl": "",
* "serverUrl": "",
* "changelog": ""
* }
*
*
* @author bwcx_jzy
* @since 2021/9/19
*/
@Data
@Slf4j
public class RemoteVersion {
/**
* 主 url 用于拉取远程版本信息
*
* 1. https://jpom.top/docs/release-versions.json
*/
private static final String DEFAULT_URL = "https://jpom.top/docs/release-versions.json";
private static final String BETA_URL = "https://jpom.top/docs/beta-versions.json";
private static String remoteVersionUrl;
/**
* 检查间隔时间
*/
private static final int CHECK_INTERVAL = 24;
/**
* 版本信息
*/
private String tagName;
/**
* 插件端下载地址
*/
private String agentUrl;
/**
* 服务端下载地址
*/
private String serverUrl;
/**
* 更新日志 (远程url)
*/
private String changelogUrl;
/**
* 更新日志
*/
private String changelog;
/**
* 上次获取时间
*/
private Long lastTime;
/**
* 是否有新版本
*/
private Boolean upgrade;
/**
* 是否为 beta 版本
*/
private Boolean beta;
public static void setRemoteVersionUrl(String remoteVersionUrl) {
RemoteVersion.remoteVersionUrl = remoteVersionUrl;
}
/**
* 获取 版本检查的 url
*
* @return 远程地址
*/
private static String loadDefaultUrl() {
boolean beta = betaRelease();
return beta ? BETA_URL : DEFAULT_URL;
}
/**
* 判断当前是否加入 beta 计划
*
* @return true 已经加入 false 未加入
*/
public static boolean betaRelease() {
String betaRelease = SystemPropsUtil.get("JOIN_JPOM_BETA_RELEASE", StrUtil.EMPTY);
return Convert.toBool(betaRelease, false);
}
public static void changeBetaRelease(String beta) {
SystemPropsUtil.set("JOIN_JPOM_BETA_RELEASE", beta);
}
/**
* 获取远程最新版本
*
* @return 版本信息
*/
public static RemoteVersion loadRemoteInfo() {
String body = StrUtil.EMPTY;
try {
String remoteVersionUrl = StrUtil.emptyToDefault(RemoteVersion.remoteVersionUrl, loadDefaultUrl());
remoteVersionUrl = Validator.isUrl(remoteVersionUrl) ? remoteVersionUrl : loadDefaultUrl();
// 获取缓存中到信息
RemoteVersion remoteVersion = RemoteVersion.loadTransitUrl(remoteVersionUrl);
if (remoteVersion == null || StrUtil.isEmpty(remoteVersion.getTagName())) {
// 没有版本信息
return null;
}
// 缓存信息
RemoteVersion.cacheLoadTime(remoteVersion);
return remoteVersion;
} catch (Exception e) {
log.warn("获取远程版本信息失败:{} {}", e.getMessage(), body);
return null;
}
}
/**
* 获取第一层信息,用于中转
*
* @param remoteVersionUrl 请url
* @return 中转URL
*/
private static RemoteVersion loadTransitUrl(String remoteVersionUrl) {
String body = StrUtil.EMPTY;
try {
log.debug("use remote version url: {}", remoteVersionUrl);
HttpRequest request = HttpUtil.createGet(remoteVersionUrl, true);
request.timeout(10 * 1000);
try (HttpResponse execute = request.execute()) {
body = execute.body();
}
//
JSONObject jsonObject = JSONObject.parseObject(body);
RemoteVersion remoteVersion = jsonObject.to(RemoteVersion.class);
if (StrUtil.isAllNotEmpty(remoteVersion.getTagName(), remoteVersion.getAgentUrl(), remoteVersion.getServerUrl(), remoteVersion.getServerUrl())) {
return remoteVersion;
}
String jumpUrl = jsonObject.getString("url");
if (StrUtil.isEmpty(jumpUrl)) {
return null;
}
return loadTransitUrl(jumpUrl);
} catch (Exception e) {
log.warn("获取远程版本信息失败:{} {}", e.getMessage(), body);
return null;
}
}
/**
* 缓存信息
*
* @param remoteVersion 远程版本信息
*/
private static void cacheLoadTime(RemoteVersion remoteVersion) {
remoteVersion = ObjectUtil.defaultIfNull(remoteVersion, new RemoteVersion());
remoteVersion.setLastTime(SystemClock.now());
// 判断是否可以升级
boolean isDebug = BooleanUtil.toBoolean(SystemUtil.get("JPOM_IS_DEBUG", ""));
String jpomType = SystemUtil.get("JPOM_TYPE", "");
Type type = EnumUtil.fromStringQuietly(Type.class, jpomType);
Assert.notNull(type, "没有配置正确的环境变量");
if (!isDebug) {
String version = SystemUtil.get("JPOM_VERSION", "");
String tagName = remoteVersion.getTagName();
tagName = StrUtil.removePrefixIgnoreCase(tagName, "v");
remoteVersion.setUpgrade(StrUtil.compareVersion(version, tagName) < 0);
} else {
remoteVersion.setUpgrade(false);
}
// 检查是否存在下载地址
String remoteUrl = type.getRemoteUrl(remoteVersion);
if (StrUtil.isEmpty(remoteUrl)) {
remoteVersion.setUpgrade(false);
}
// 获取 changelog
String changelogUrl = remoteVersion.getChangelogUrl();
if (StrUtil.isNotEmpty(changelogUrl)) {
try (HttpResponse execute = HttpUtil.createGet(changelogUrl, true).execute()) {
String body = execute.body();
remoteVersion.setChangelog(body);
}
}
//
File file = getFile();
FileUtil.writeUtf8String(remoteVersion.toString(), file);
}
/**
* 当前缓存中的 远程版本信息
*
* @return RemoteVersion
*/
public static RemoteVersion cacheInfo() {
File file = getFile();
if (!FileUtil.isFile(file)) {
return null;
}
RemoteVersion remoteVersion = null;
String fileStr = StrUtil.EMPTY;
try {
fileStr = FileUtil.readUtf8String(file);
if (StrUtil.isEmpty(fileStr)) {
return null;
}
remoteVersion = JSONObject.parseObject(fileStr).to(RemoteVersion.class);
} catch (Exception e) {
log.warn("解析远程版本信息失败:{} {}", e.getMessage(), fileStr);
}
// 判断上次获取时间
Long lastTime = remoteVersion == null ? 0 : remoteVersion.getLastTime();
lastTime = ObjectUtil.defaultIfNull(lastTime, 0L);
long interval = SystemClock.now() - lastTime;
return interval >= TimeUnit.HOURS.toMillis(CHECK_INTERVAL) ? null : remoteVersion;
}
/**
* 保存的文件
*
* @return file
*/
private static File getFile() {
String cacheFile = SystemUtil.get("JPOM_REMOTE_VERSION_CACHE_FILE", "");
Assert.state(StrUtil.isNotEmpty(cacheFile), "没有配置正确的环境变量");
return FileUtil.file(cacheFile);
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}