|
@@ -2,6 +2,7 @@ package com.qmth.boot.data.upgrade.config;
|
|
|
|
|
|
import com.qmth.boot.data.upgrade.annotation.DataUpgradeVersion;
|
|
import com.qmth.boot.data.upgrade.annotation.DataUpgradeVersion;
|
|
import com.qmth.boot.data.upgrade.model.BootAppInfo;
|
|
import com.qmth.boot.data.upgrade.model.BootAppInfo;
|
|
|
|
+import com.qmth.boot.data.upgrade.model.RunMode;
|
|
import com.qmth.boot.data.upgrade.service.DataInitService;
|
|
import com.qmth.boot.data.upgrade.service.DataInitService;
|
|
import com.qmth.boot.data.upgrade.service.DataUpgradeService;
|
|
import com.qmth.boot.data.upgrade.service.DataUpgradeService;
|
|
import com.qmth.boot.data.upgrade.utils.ClassHelper;
|
|
import com.qmth.boot.data.upgrade.utils.ClassHelper;
|
|
@@ -37,25 +38,30 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
public void onApplicationEvent(ApplicationPreparedEvent event) {
|
|
public void onApplicationEvent(ApplicationPreparedEvent event) {
|
|
try {
|
|
try {
|
|
properties = new DataUpgradeProperties(event.getApplicationContext().getEnvironment());
|
|
properties = new DataUpgradeProperties(event.getApplicationContext().getEnvironment());
|
|
- if (!properties.getEnable()) {
|
|
|
|
- // 未启用时,不再进行后续处理
|
|
|
|
- return;
|
|
|
|
|
|
+
|
|
|
|
+ if (RunMode.INSTALL == properties.getRunMode()) {
|
|
|
|
+ // 首次安装模式,仅执行数据初始化
|
|
|
|
+ this.handlerInstall();
|
|
|
|
+ // 执行完后默认退出程序
|
|
|
|
+ System.exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
- if (properties.getFirstInstall()) {
|
|
|
|
- // 首次安装时,仅执行数据初始化
|
|
|
|
- this.handlerDataInit();
|
|
|
|
- } else {
|
|
|
|
- // 否则执行数据升级
|
|
|
|
- this.handlerDataUpgrade();
|
|
|
|
|
|
+ if (RunMode.UPGRADE == properties.getRunMode()) {
|
|
|
|
+ // 升级模式,仅执行数据升级
|
|
|
|
+ this.handlerUpgrade();
|
|
|
|
+ // 执行完后默认退出程序
|
|
|
|
+ System.exit(1);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 启动模式
|
|
|
|
+ this.handlerStart();
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
- log.error("数据操作异常终止!原因:{}", e.getMessage(), e);
|
|
|
|
|
|
+ log.error("程序异常终止!原因:{}", e.getMessage(), e);
|
|
System.exit(1);
|
|
System.exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public void handlerDataInit() {
|
|
|
|
|
|
+ public void handlerInstall() {
|
|
try (HikariDataSource dataSource = this.initDataSource()) {
|
|
try (HikariDataSource dataSource = this.initDataSource()) {
|
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
|
|
|
|
|
@@ -74,22 +80,20 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
throw new RuntimeException("不允许存在多个数据初始化的具体实现!");
|
|
throw new RuntimeException("不允许存在多个数据初始化的具体实现!");
|
|
}
|
|
}
|
|
|
|
|
|
- log.warn("*************** data init start ***************");
|
|
|
|
try {
|
|
try {
|
|
|
|
+ log.warn("*************** data init start ***************");
|
|
services.get(0).process(jdbcTemplate);
|
|
services.get(0).process(jdbcTemplate);
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
- throw new RuntimeException("SQL语句执行异常!", e);
|
|
|
|
|
|
+ throw new RuntimeException("数据初始化执行异常!" + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
|
|
// 数据初始化完成后,初始应用信息表
|
|
// 数据初始化完成后,初始应用信息表
|
|
this.initBootAppInfo(jdbcTemplate, properties.getAppCode(), properties.getAppVersion());
|
|
this.initBootAppInfo(jdbcTemplate, properties.getAppCode(), properties.getAppVersion());
|
|
log.warn("*************** data init finish ***************");
|
|
log.warn("*************** data init finish ***************");
|
|
- } catch (Exception e) {
|
|
|
|
- throw new RuntimeException(e.getMessage(), e);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public void handlerDataUpgrade() {
|
|
|
|
|
|
+ public void handlerUpgrade() {
|
|
try (HikariDataSource dataSource = this.initDataSource()) {
|
|
try (HikariDataSource dataSource = this.initDataSource()) {
|
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
|
|
|
|
|
@@ -105,7 +109,7 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
|
|
|
|
BootAppInfo appInfo = this.queryBootAppInfo(jdbcTemplate, properties.getAppCode());
|
|
BootAppInfo appInfo = this.queryBootAppInfo(jdbcTemplate, properties.getAppCode());
|
|
if (appInfo == null) {
|
|
if (appInfo == null) {
|
|
- throw new RuntimeException("【应用信息表】中未找到匹配的数据!appCode:" + properties.getAppCode());
|
|
|
|
|
|
+ throw new RuntimeException("【应用信息表】版本数据未找到!appCode:" + properties.getAppCode());
|
|
}
|
|
}
|
|
|
|
|
|
log.warn("待升级应用码:{} 待升级应用版本号:{} 当前应用码:{} 当前应用版本号:{} locked:{}", properties.getAppCode(),
|
|
log.warn("待升级应用码:{} 待升级应用版本号:{} 当前应用码:{} 当前应用版本号:{} locked:{}", properties.getAppCode(),
|
|
@@ -115,14 +119,14 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
if (compareValue > 0) {
|
|
if (compareValue > 0) {
|
|
throw new RuntimeException("待升级的版本号不能低于当前版本号!");
|
|
throw new RuntimeException("待升级的版本号不能低于当前版本号!");
|
|
}
|
|
}
|
|
|
|
+
|
|
if (compareValue == 0) {
|
|
if (compareValue == 0) {
|
|
log.warn("跳过数据升级,版本号一致!");
|
|
log.warn("跳过数据升级,版本号一致!");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 数据升级实现 按版本号由小到大排序
|
|
Map<String, DataUpgradeService> serviceMaps = this.matchServices(appInfo.getAppVersion(), properties.getAppVersion());
|
|
Map<String, DataUpgradeService> serviceMaps = this.matchServices(appInfo.getAppVersion(), properties.getAppVersion());
|
|
-
|
|
|
|
- // 按版本号由小到大排序
|
|
|
|
List<String> versionKeys = new ArrayList<>(serviceMaps.keySet());
|
|
List<String> versionKeys = new ArrayList<>(serviceMaps.keySet());
|
|
versionKeys.sort(new VersionComparator());
|
|
versionKeys.sort(new VersionComparator());
|
|
|
|
|
|
@@ -134,11 +138,11 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
|
|
|
|
try {
|
|
try {
|
|
for (String version : versionKeys) {
|
|
for (String version : versionKeys) {
|
|
- log.warn("*************** data upgrade version:{} start ***************", version);
|
|
|
|
|
|
+ log.warn("*************** version:{} data upgrade start ***************", version);
|
|
serviceMaps.get(version).process(jdbcTemplate);
|
|
serviceMaps.get(version).process(jdbcTemplate);
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
- throw new RuntimeException("SQL语句执行异常!", e);
|
|
|
|
|
|
+ throw new RuntimeException("数据升级执行异常!" + e.getMessage(), e);
|
|
} finally {
|
|
} finally {
|
|
// 升级解锁
|
|
// 升级解锁
|
|
unLock(jdbcTemplate, appInfo.getAppCode());
|
|
unLock(jdbcTemplate, appInfo.getAppCode());
|
|
@@ -148,8 +152,29 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
// 数据升级完成后,更新应用信息表
|
|
// 数据升级完成后,更新应用信息表
|
|
this.updateBootAppInfo(jdbcTemplate, properties.getAppCode(), properties.getAppVersion());
|
|
this.updateBootAppInfo(jdbcTemplate, properties.getAppCode(), properties.getAppVersion());
|
|
log.warn("*************** data upgrade finish ***************");
|
|
log.warn("*************** data upgrade finish ***************");
|
|
- } catch (Exception e) {
|
|
|
|
- throw new RuntimeException(e.getMessage(), e);
|
|
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void handlerStart() {
|
|
|
|
+ try (HikariDataSource dataSource = this.initDataSource()) {
|
|
|
|
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
|
|
|
+
|
|
|
|
+ if (!this.existBootAppInfo(jdbcTemplate)) {
|
|
|
|
+ throw new RuntimeException("【应用信息表】不存在!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ BootAppInfo appInfo = this.queryBootAppInfo(jdbcTemplate, properties.getAppCode());
|
|
|
|
+ if (appInfo == null) {
|
|
|
|
+ throw new RuntimeException("【应用信息表】版本数据未找到!appCode:" + properties.getAppCode());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.warn("配置应用码:{} 配置应用版本号:{} 当前应用码:{} 当前应用版本号:{}", properties.getAppCode(),
|
|
|
|
+ properties.getAppVersion(), appInfo.getAppCode(), appInfo.getAppVersion());
|
|
|
|
+
|
|
|
|
+ int compareValue = new VersionComparator().compare(appInfo.getAppVersion(), properties.getAppVersion());
|
|
|
|
+ if (compareValue != 0) {
|
|
|
|
+ throw new RuntimeException("配置中的版本号与数据库中的应用版本号不一致!");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -182,7 +207,7 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
if (vc.compare(implVersion, currentVersion) > 0 && targetVersionCompare <= 0) {
|
|
if (vc.compare(implVersion, currentVersion) > 0 && targetVersionCompare <= 0) {
|
|
log.debug("implClass:{} implVersion:{}", implClass.getSimpleName(), implVersion);
|
|
log.debug("implClass:{} implVersion:{}", implClass.getSimpleName(), implVersion);
|
|
if (serviceMaps.containsKey(implVersion)) {
|
|
if (serviceMaps.containsKey(implVersion)) {
|
|
- throw new RuntimeException("同个版本数据升级的实现出现重复!@DataUpgradeVersion:" + implVersion);
|
|
|
|
|
|
+ throw new RuntimeException("同个版本数据升级的实现出现重复!版本:" + implVersion);
|
|
}
|
|
}
|
|
|
|
|
|
try {
|
|
try {
|
|
@@ -191,14 +216,14 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
serviceMaps.put(implVersion, (DataUpgradeService) constructor.newInstance());
|
|
serviceMaps.put(implVersion, (DataUpgradeService) constructor.newInstance());
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
- throw new RuntimeException(e.getMessage(), e);
|
|
|
|
|
|
+ log.warn("{} class newInstance fail. {}", implClass.getSimpleName(), e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!existTargetVersionImpl) {
|
|
if (!existTargetVersionImpl) {
|
|
- log.warn("未找到版本“{}”数据升级的具体实现!{}:{}", targetVersion, BASE_PACKAGE, properties.getBasePackage());
|
|
|
|
- throw new RuntimeException("未找到数据升级的具体实现!");
|
|
|
|
|
|
+ log.warn("未找到数据升级的具体实现!版本:{} {}:{}", targetVersion, BASE_PACKAGE, properties.getBasePackage());
|
|
|
|
+ throw new RuntimeException("未找到数据升级的具体实现!版本:" + targetVersion);
|
|
}
|
|
}
|
|
|
|
|
|
return serviceMaps;
|
|
return serviceMaps;
|
|
@@ -256,7 +281,7 @@ public class DataUpgradeListener implements ApplicationListener<ApplicationPrepa
|
|
|
|
|
|
private boolean existBootAppInfo(JdbcTemplate jdbcTemplate) {
|
|
private boolean existBootAppInfo(JdbcTemplate jdbcTemplate) {
|
|
try {
|
|
try {
|
|
- // 是否存在应用信息表:boot_app_info
|
|
|
|
|
|
+ // 是否存在应用信息表
|
|
List<String> exists = jdbcTemplate.queryForList("SHOW TABLES LIKE 'boot_app_info'", String.class);
|
|
List<String> exists = jdbcTemplate.queryForList("SHOW TABLES LIKE 'boot_app_info'", String.class);
|
|
return !exists.isEmpty();
|
|
return !exists.isEmpty();
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|