From dd9700048ab2e999a73d77771d357d409f4ff2cd Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 22 Jan 2024 17:22:05 +0800 Subject: [PATCH] =?UTF-8?q?add=20-=20=E6=96=B0=E5=A2=9E=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E7=9A=84=E6=89=A7=E8=A1=8C=E9=80=BB=E8=BE=91?= =?UTF-8?q?,=20=E7=A1=AE=E4=BF=9D=E4=BB=A5=E5=90=8E=E7=9A=84=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E8=BF=AD=E4=BB=A3=E5=8F=AA=E9=9C=80=E8=A6=81=E4=BF=9D?= =?UTF-8?q?=E8=AF=81=E8=84=9A=E6=9C=AC=E6=89=A7=E8=A1=8C=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E5=8D=B3=E5=8F=AF.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/sql/readme.md | 15 ++ .../src/main/resources/sql/upgrade_to_130.sql | 12 ++ .../initializer/ExtDatabaseInitializer.java | 4 +- .../VersionUpgradeInitializer.java | 141 ++++++++++++++++++ 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 workflow-engine-core/src/main/resources/sql/readme.md create mode 100644 workflow-engine-core/src/main/resources/sql/upgrade_to_130.sql create mode 100644 workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/VersionUpgradeInitializer.java diff --git a/workflow-engine-core/src/main/resources/sql/readme.md b/workflow-engine-core/src/main/resources/sql/readme.md new file mode 100644 index 000000000..549491e9f --- /dev/null +++ b/workflow-engine-core/src/main/resources/sql/readme.md @@ -0,0 +1,15 @@ +## 本包的 sql 脚本一般不需要人工执行 + +> 简单描述下本报下的文件执行逻辑和分类 +> +> - `ext_ax`开头的文件一般为建表语句 +> - `upgrade`开头的文件一般为升级脚本 + +### ext_ax_xxxx + +> 这类文件是在版本更新时, 新建全新的表, 文件命名也是有一定的规范, 必须是以 `ext_ax_`开头,否则会自动忽略. + +### upgrade_to_xxxx + +> 这类文件是在版本更新时, 一般会更新表的结构,创建新的索引,修改表结构等, 文件命名也是有一定的规范, 必须是以 `upgrade_to` +> 开头, 并且后面更纯数字的版本号, 否则会自动忽略. diff --git a/workflow-engine-core/src/main/resources/sql/upgrade_to_130.sql b/workflow-engine-core/src/main/resources/sql/upgrade_to_130.sql new file mode 100644 index 000000000..f7f9c8d85 --- /dev/null +++ b/workflow-engine-core/src/main/resources/sql/upgrade_to_130.sql @@ -0,0 +1,12 @@ +-- 创建唯一索引 +create unique index uk_proc_task on EXT_AX_HI_TASKINST (proc_inst_id, task_id); + +-- 清洗历史版本的审批日志数据 +insert into ext_ax_hi_taskinst (proc_inst_id, task_id, task_definition_key, status, assignee) +select PROC_INST_ID_, ID_, TASK_DEF_KEY_, 'PROCESSING', ifnull(ASSIGNEE_, '') as ASSIGNEE_ +from act_hi_taskinst +where END_TIME_ is null + and ID_ not in (select distinct task_id from ext_ax_hi_taskinst) + + + diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/ExtDatabaseInitializer.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/ExtDatabaseInitializer.java index 56e2d51c7..aa41a9f4c 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/ExtDatabaseInitializer.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/ExtDatabaseInitializer.java @@ -35,7 +35,7 @@ import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCH @Slf4j @AllArgsConstructor public class ExtDatabaseInitializer implements ApplicationRunner { - + private static final String FILE_PREFIX = "ext_ax_"; private final JdbcTemplate jdbcTemplate; private final ResourceLoader resourceLoader; private final ApplicationContext applicationContext; @@ -64,7 +64,7 @@ public class ExtDatabaseInitializer implements ApplicationRunner { } private List localSqlFiles() throws IOException { - return Arrays.stream(resourcePatternResolver.getResources("classpath:sql/ext_ax_*.sql")) + return Arrays.stream(resourcePatternResolver.getResources("classpath:sql/" + FILE_PREFIX + "*.sql")) .map(Resource::getFilename).collect(Collectors.toList()); } diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/VersionUpgradeInitializer.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/VersionUpgradeInitializer.java new file mode 100644 index 000000000..62d5b90fe --- /dev/null +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/initializer/VersionUpgradeInitializer.java @@ -0,0 +1,141 @@ +package cn.axzo.workflow.server.initializer; + +import cn.azxo.framework.common.utils.LogUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.flowable.spring.SpringProcessEngineConfiguration; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_FALSE; + +/** + * 版本升级脚本 + * + * @author wangli + * @since 2024/1/22 16:02 + */ +@Component +@Slf4j +@AllArgsConstructor +public class VersionUpgradeInitializer implements ApplicationRunner { + private static final String FILE_PREFIX = "upgrade_to_"; + private static final String COLUMN_NAME = "workflow.engine.version"; + private final JdbcTemplate jdbcTemplate; + private final ResourceLoader resourceLoader; + private final ApplicationContext applicationContext; + private ResourcePatternResolver resourcePatternResolver; + + @Override + public void run(ApplicationArguments args) throws Exception { + SpringProcessEngineConfiguration springProcessEngineConfiguration = + (SpringProcessEngineConfiguration) applicationContext.getBean("springProcessEngineConfiguration"); + if (Objects.equals(DB_SCHEMA_UPDATE_FALSE, springProcessEngineConfiguration.getDatabaseSchemaUpdate())) { + return; + } + + String currentVersion = selectWorkflowEngineVersion(); + AtomicBoolean result = new AtomicBoolean(true); + List newVersions = new ArrayList<>(); + localSqlFiles().forEach(i -> { + int upgradeVersion = Integer.parseInt(i.replace(FILE_PREFIX, "").replace(".sql", "").replace(".", "")); + int current = Integer.parseInt(currentVersion.replace(".", "")); + if (upgradeVersion > current) { + newVersions.add(upgradeVersion); + log.debug("execute sql script: {}", i); + try { + // executeSqlScript(i); + } catch (Exception e) { + LogUtil.error(LogUtil.ErrorType.ERROR_SQL, "升级服务数据库版本发生异常,文件: {}, 异常信息: {}", i, e.getMessage()); + result.compareAndSet(true, false); + } + } + }); + updateVersion(result, newVersions); + } + + private void updateVersion(AtomicBoolean result, List newVersions) { + if (result.get() && !newVersions.isEmpty()) { + String updateSql = "UPDATE act_ge_property SET VALUE_ = ? where NAME_ = '" + COLUMN_NAME + "'"; + jdbcTemplate.update(updateSql, findMaxVersion(newVersions)); + } + } + + private String findMaxVersion(List newVersions) { + // 使用 forEach 遍历列表 + int max = newVersions.get(0); + for (Integer i : newVersions) { + // 如果当前元素大于 max,则更新 max + if (i > max) { + max = i; + } + } + + String[] nums = String.valueOf(max).split(""); + String maxVersion = ""; + for (int i = 0; i < nums.length; i++) { + if (i != nums.length - 1) { + maxVersion += nums[i] + "."; + } else { + maxVersion += nums[i]; + } + } + log.info("max version: {}", maxVersion); + return maxVersion; + } + + private void executeSqlScript(String fileName) { + Resource resource = resourceLoader.getResource("classpath:sql/" + fileName.toLowerCase()); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) { + StringBuilder scriptBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + scriptBuilder.append(line); + } + + // Split SQL statements and execute each one + String[] sqlStatements = scriptBuilder.toString().split(";"); + for (String sql : sqlStatements) { + jdbcTemplate.execute(sql); + } + } catch (IOException e) { + // Handle IOException + e.printStackTrace(); + } + } + + private List localSqlFiles() throws IOException { + return Arrays.stream(resourcePatternResolver.getResources("classpath:sql/" + FILE_PREFIX + "*.sql")) + .map(Resource::getFilename).collect(Collectors.toList()); + } + + private String selectWorkflowEngineVersion() { + String query = "select VALUE_ from act_ge_property where NAME_ = ?"; + String search = "workflow.engine.version"; + String version; + try { + version = jdbcTemplate.queryForObject(query, new Object[]{search}, String.class); + } catch (Exception e) { + jdbcTemplate.execute("insert into act_ge_property values ('workflow.engine.version', '1.2.1', 1)"); + version = "1.2.1"; + } + return version; + } +}