Carry actual flow state and freeze callback round identity
Local review candidate only. Explicitly selected inherited prerequisites and prior repair patches; unrelated WIP and independent MQ fixes are excluded. No push or deployment authorized.
This commit is contained in:
@@ -16,6 +16,10 @@ on:
|
||||
description: '构建前清空 maven m2 缓存'
|
||||
required: false
|
||||
default: 'false'
|
||||
tests_only:
|
||||
description: '只验证测试和 JAR,不构建推送镜像或通知建档'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
jobs:
|
||||
build-push:
|
||||
@@ -36,6 +40,8 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git clone --depth 1 --branch main "http://x-access-token:${GITHUB_TOKEN}@gitea.yunhaixingtong.com/${{ github.repository }}.git" /tmp/src
|
||||
git -C /tmp/src fetch --depth 1 origin "$GITHUB_SHA"
|
||||
git -C /tmp/src checkout --detach FETCH_HEAD
|
||||
cp -a /tmp/src/. .
|
||||
rm -rf /tmp/src
|
||||
# 取提交备注首行,脱去换行/双引号/反斜杠(避免破坏 webhook JSON),截断到 200 字符
|
||||
@@ -64,6 +70,7 @@ jobs:
|
||||
# GITHUB_RUN_ID 实例级唯一,再拼时间戳兜底。
|
||||
BUILD_CONTAINER="mavenbuild-${GITHUB_RUN_ID:-0}-$(date +%s)"
|
||||
echo "BUILD_CONTAINER=${BUILD_CONTAINER}"
|
||||
trap 'docker rm -f "$BUILD_CONTAINER" >/dev/null 2>&1 || true' EXIT
|
||||
docker rm -f "$BUILD_CONTAINER" 2>/dev/null || true
|
||||
docker run -d --name "$BUILD_CONTAINER" \
|
||||
--network infra-infra-net \
|
||||
@@ -71,13 +78,33 @@ jobs:
|
||||
-w /build maven:3.6.3-jdk-8 sleep 3600
|
||||
docker cp "${PWD}/." "$BUILD_CONTAINER":/build/
|
||||
docker exec "$BUILD_CONTAINER" sh -c "printf '%s' '<settings><profiles><profile><id>nexus-repo</id><repositories><repository><id>nexus-internal</id><url>http://nexus:8081/repository/maven-public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots></repository></repositories></profile></profiles><activeProfiles><activeProfile>nexus-repo</activeProfile></activeProfiles></settings>' > /root/.m2/settings.xml"
|
||||
docker exec "$BUILD_CONTAINER" sh -c 'cd /build && mvn -B -DskipTests clean package'
|
||||
# 为真实 MySQL 测试创建本次 job 独占的临时数据库;不映射宿主端口、不连接业务库。
|
||||
DB_CONTAINER="${BUILD_CONTAINER}-db"
|
||||
trap 'docker rm -f "$BUILD_CONTAINER" "$DB_CONTAINER" >/dev/null 2>&1 || true' EXIT
|
||||
export MYSQL_ROOT_PASSWORD=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n')
|
||||
export MYSQL_PASSWORD=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n')
|
||||
docker create --name "$DB_CONTAINER" --network infra-infra-net \
|
||||
-e MYSQL_DATABASE=flowcenter_ci -e MYSQL_USER=flow_ci \
|
||||
-e MYSQL_PASSWORD -e MYSQL_ROOT_PASSWORD mysql:8.0 --skip-log-bin >/dev/null
|
||||
docker cp "${PWD}/ci/flow-test-schema.sql" "$DB_CONTAINER":/docker-entrypoint-initdb.d/001-schema.sql
|
||||
docker start "$DB_CONTAINER" >/dev/null
|
||||
ready=0
|
||||
for n in $(seq 1 60); do
|
||||
if docker exec "$DB_CONTAINER" sh -c 'MYSQL_PWD="$MYSQL_PASSWORD" mysql -h127.0.0.1 -u"$MYSQL_USER" "$MYSQL_DATABASE" -Nse "SELECT 1" >/dev/null 2>&1'; then ready=1; break; fi
|
||||
sleep 2
|
||||
done
|
||||
[ "$ready" -eq 1 ] || { echo 'Isolated CI MySQL did not become ready' >&2; exit 1; }
|
||||
export CI_TEST_DB_URL="jdbc:mysql://${DB_CONTAINER}:3306/flowcenter_ci?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"
|
||||
export CI_TEST_DB_USER=flow_ci CI_TEST_DB_PASSWORD="$MYSQL_PASSWORD"
|
||||
docker exec -e CI_TEST_DB_URL -e CI_TEST_DB_USER -e CI_TEST_DB_PASSWORD \
|
||||
"$BUILD_CONTAINER" sh -c 'cd /build && sh ci/test-gate.sh clean package'
|
||||
docker exec "$BUILD_CONTAINER" sh -c 'cd /build/target && cp *.jar app.jar'
|
||||
mkdir -p "${PWD}/target"
|
||||
docker cp "$BUILD_CONTAINER":/build/target/app.jar "${PWD}/target/app.jar"
|
||||
docker rm -f "$BUILD_CONTAINER"
|
||||
|
||||
- name: 构建并推送镜像
|
||||
if: ${{ inputs.tests_only != 'true' }}
|
||||
run: |
|
||||
set -e
|
||||
TAG=$(echo "$GITHUB_SHA" | cut -c1-8)
|
||||
@@ -88,6 +115,7 @@ jobs:
|
||||
|
||||
# 通知 projman:webhook 收到后只建档 Release(status=pending),部署由运维在 DeployTab 手动触发(App.deployMode=manual)
|
||||
- name: 通知 projman 建档(部署由运维手动触发)
|
||||
if: ${{ inputs.tests_only != 'true' }}
|
||||
run: |
|
||||
curl -sS -X POST "http://192.168.10.160:8090/projman/api/deploy/webhook" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# FL 指定门禁与独立 MySQL
|
||||
|
||||
`test-gate.sh` 是 Gitea 与本地等价 CI 共用的入口。无参运行 `test`;工作流使用
|
||||
`sh ci/test-gate.sh clean package`,真实测试未通过不会生成待发布 JAR,后续镜像步骤不会运行。
|
||||
所有指定类必须存在;Surefire 不允许零测试;Hibernate 固定 `ddl-auto=validate`。
|
||||
|
||||
工作流在 `infra-infra-net` 内新建 `${BUILD_CONTAINER}-db`,镜像 `mysql:8.0`,不映射宿主端口。
|
||||
在启动之前把 `flow-test-schema.sql` 复制进初始化目录;该文件只含 14 张表的结构,不含业务数据。
|
||||
镜像初始化阶段建立测试 schema,测试阶段只 validate。每个 job 的数据库容器名和随机凭据独立,
|
||||
EXIT trap 回收 Maven/MySQL 容器;不访问 160 业务库。
|
||||
|
||||
随机凭据仅经容器环境变量传递,不写仓库或日志。Maven 子容器必须获得:
|
||||
|
||||
- `CI_TEST_DB_URL`:MySQL JDBC URL;schema 必须为 `flowcenter_ci` 或 `flowcenter_ci_*`。
|
||||
- `CI_TEST_DB_USER`、`CI_TEST_DB_PASSWORD`:本次数据库的专用账号与密码。
|
||||
|
||||
脚本只允许 localhost、127.0.0.1 或 `mavenbuild-*-db` 主机,随后映射为 Spring datasource 环境变量。
|
||||
`OapiFlowTasksByBizTest` 在任何 cleanDb 前检查 JDBC 实际连接的 host/schema,防止 profile 覆盖错误。
|
||||
CI 场景必须实际连接 `flowcenter_ci*`,不能悄悄改用默认开发库;11 项继续为真 MySQL 测试。
|
||||
|
||||
本地等价运行:在独立测试库按此 schema 初始化后,通过进程环境设置上述三个变量,
|
||||
再执行 `sh ci/test-gate.sh clean package`。凭据不要写入命令历史或提交到仓库。
|
||||
|
||||
本次已在本机 MySQL 8.0.45 做正反等价验证:完整 schema 通过,空 schema 验证失败且不生成 JAR。
|
||||
三个 workflow 的手动入口新增 `tests_only=true`(默认),可以在 runner 上只验测试/JAR,不推镜像或通知建档。
|
||||
本机没有 Docker,Gitea runner 的容器启动、镜像拉取和网络连通未实跑;这些仍需在 runner 上验证,
|
||||
不能将等价 Maven 证据描述为实际 Gitea workflow 已通过。
|
||||
|
||||
实体结构变更时应显式刷新 SQL 快照并重新验证;不能把 validate 改为 update 来绕过缺表或缺列。
|
||||
@@ -0,0 +1,330 @@
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_app` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`app_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`app_name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`enabled` int NOT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`sort_no` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_app_sch_key` (`sch_id`,`app_key`),
|
||||
KEY `idx_flw_app_sch_enabled` (`sch_id`,`enabled`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_assignee_map` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`dept_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`dept_name` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`user_id` int NOT NULL,
|
||||
`user_name` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_map_sch_dept_user` (`sch_id`,`dept_key`,`user_id`),
|
||||
KEY `idx_flw_map_sch_dept` (`sch_id`,`dept_key`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_attachment` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`field_key` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`file_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`file_path` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`file_size` bigint DEFAULT NULL,
|
||||
`instance_id` bigint NOT NULL,
|
||||
`mime_type` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`web_url` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_flw_att_inst` (`instance_id`,`sch_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_branch` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`branch_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`instance_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_branch_inst_key` (`instance_id`,`branch_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_callback_log` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`biz_id` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`biz_type` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`event` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`event_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`instance_id` bigint NOT NULL,
|
||||
`last_error` varchar(1000) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`last_http_status` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`next_retry_time` datetime DEFAULT NULL,
|
||||
`payload_json` longtext COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`push_time` datetime DEFAULT NULL,
|
||||
`reg_id` bigint NOT NULL,
|
||||
`retry_count` int NOT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`resp_body` text COLLATE utf8mb4_general_ci,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_log_event` (`event_id`),
|
||||
KEY `idx_flw_log_scan` (`status`,`next_retry_time`),
|
||||
KEY `idx_flw_log_inst` (`instance_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_callback_reg` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`app_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`callback_url` varchar(500) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`event_types` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`flow_guid` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`secret` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`base_path` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_reg_sch_app_flow` (`sch_id`,`app_key`,`flow_guid`),
|
||||
KEY `idx_flw_reg_flow` (`sch_id`,`flow_guid`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_cc` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`instance_id` bigint NOT NULL COMMENT '归属办件',
|
||||
`sch_id` bigint NOT NULL COMMENT '租户键(冗余,列表免 join)',
|
||||
`node_id` varchar(64) NOT NULL COMMENT '定义节点 id',
|
||||
`node_name` varchar(128) DEFAULT NULL COMMENT '节点名快照',
|
||||
`user_id` int NOT NULL COMMENT '接收人 id',
|
||||
`user_name` varchar(128) DEFAULT NULL COMMENT '接收人姓名快照',
|
||||
`sent_time` datetime(3) NOT NULL COMMENT '抄送时间(节点激活时刻,毫秒)',
|
||||
`create_by` varchar(64) DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(64) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_flw_cc_user` (`user_id`,`sent_time`),
|
||||
KEY `idx_flw_cc_inst` (`instance_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='抄送留痕(NOTIFY 节点逐接收人一行)';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_def` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`code` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`content_json` longtext COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`flow_guid` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`form_id` bigint DEFAULT NULL,
|
||||
`item_code` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`publish_time` datetime DEFAULT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`version` int NOT NULL,
|
||||
`app_key` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`change_log` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`form_uuid` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`form_version` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_def_sch_code_ver` (`sch_id`,`code`,`version`),
|
||||
UNIQUE KEY `uk_flw_def_guid_ver` (`sch_id`,`flow_guid`,`version`),
|
||||
KEY `idx_flw_def_guid` (`sch_id`,`flow_guid`,`status`,`version`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_dept` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`dept_name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`source_group_id` int DEFAULT NULL,
|
||||
`status` int NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_dept_sch_srcgroup` (`sch_id`,`source_group_id`),
|
||||
KEY `idx_flw_dept_sch_status` (`sch_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_dept_member` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`dept_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`user_id` int NOT NULL,
|
||||
`user_name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_dept_member` (`dept_id`,`user_id`),
|
||||
KEY `idx_flw_dept_member_dept` (`dept_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_instance` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`biz_id` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`biz_snapshot` longtext COLLATE utf8mb4_general_ci,
|
||||
`biz_title` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`biz_type` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`biz_url` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`current_nodes` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`def_code` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`def_id` bigint NOT NULL,
|
||||
`def_version` int NOT NULL,
|
||||
`finish_time` datetime DEFAULT NULL,
|
||||
`form_data_json` longtext COLLATE utf8mb4_general_ci,
|
||||
`item_code` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`item_title` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`submit_time` datetime DEFAULT NULL,
|
||||
`submitter_id` int NOT NULL,
|
||||
`submitter_name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`version` int NOT NULL,
|
||||
`apply_app_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`apply_app_key` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`assign_json` longtext COLLATE utf8mb4_general_ci,
|
||||
`apply_request_token` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`apply_round` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_instance_biz` (`sch_id`,`biz_type`,`biz_id`),
|
||||
KEY `idx_flw_inst_submitter` (`sch_id`,`submitter_id`,`status`),
|
||||
KEY `idx_flw_inst_status_time` (`sch_id`,`status`,`submit_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_route_log` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`attempt` int NOT NULL,
|
||||
`decide_time` datetime(3) NOT NULL,
|
||||
`instance_id` bigint NOT NULL,
|
||||
`node_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`node_name` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`outlet` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`raw_response` text COLLATE utf8mb4_general_ci,
|
||||
`router_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_flw_route_log_inst` (`instance_id`,`node_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_router` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`base_path` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`name` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`path` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`router_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`service_key` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`direct_host` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`reg_app_key` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_flw_router_key` (`router_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `flw_task` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`create_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_by` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`arrive_time` datetime(3) NOT NULL COMMENT '到达时间(毫秒)',
|
||||
`assignee_id` int NOT NULL,
|
||||
`assignee_name` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`deadline` datetime DEFAULT NULL,
|
||||
`handle_time` datetime(3) DEFAULT NULL COMMENT '办理时间(毫秒)',
|
||||
`instance_id` bigint NOT NULL,
|
||||
`node_id` varchar(64) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`node_name` varchar(128) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`opinion` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`sch_id` bigint NOT NULL,
|
||||
`status` int NOT NULL,
|
||||
`urge_count` int NOT NULL,
|
||||
`edge_name` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_flw_task_inst_status` (`instance_id`,`status`),
|
||||
KEY `idx_flw_task_assignee` (`assignee_id`,`status`,`arrive_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
cd "$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||
# 真实 MySQL 测试必须使用本次任务的独立 schema,禁止默认连开发/生产库。
|
||||
: "${CI_TEST_DB_URL:?CI_TEST_DB_URL is required}"
|
||||
: "${CI_TEST_DB_USER:?CI_TEST_DB_USER is required}"
|
||||
: "${CI_TEST_DB_PASSWORD:?CI_TEST_DB_PASSWORD is required}"
|
||||
case "$CI_TEST_DB_URL" in jdbc:mysql://*) ;; *) echo 'Expected a MySQL test URL' >&2; exit 2 ;; esac
|
||||
address=${CI_TEST_DB_URL#jdbc:mysql://}
|
||||
host=${address%%/*}; host=${host%%:*}
|
||||
case "$host" in localhost|127.0.0.1|mavenbuild-*-db) ;; *) echo 'Database host is outside isolated CI allowlist' >&2; exit 2 ;; esac
|
||||
schema=${address#*/}; schema=${schema%%\?*}
|
||||
case "$schema" in flowcenter_ci|flowcenter_ci_*) ;; *) echo 'Database schema is outside isolated CI prefix' >&2; exit 2 ;; esac
|
||||
export SPRING_DATASOURCE_URL="$CI_TEST_DB_URL"
|
||||
export SPRING_DATASOURCE_USERNAME="$CI_TEST_DB_USER"
|
||||
export SPRING_DATASOURCE_PASSWORD="$CI_TEST_DB_PASSWORD"
|
||||
TESTS=FlApplyRecoveryTest,FlFormBindingTest,OapiFlowApplyDefVersionTest,CallbackPropertiesTest,FlowDefAdminServicePublishContractTest,FormCenterSchemaClientTest,OapiFlowTasksByBizTest,OapiFlowP35DoneCcContractTest
|
||||
# Surefire 的选择器部分匹配也可能成功;每个指定类必须随源码存在。
|
||||
oldIFS=$IFS
|
||||
IFS=,
|
||||
for test in $TESTS; do
|
||||
[ -n "$(find src/test/java -type f -name "$test.java" -print -quit)" ] || { echo "Missing required test class: $test" >&2; exit 2; }
|
||||
done
|
||||
IFS=$oldIFS
|
||||
if [ "$#" -eq 0 ]; then set -- test; fi
|
||||
exec mvn -B "$@" -Dtest="$TESTS" -DfailIfNoTests=true -Dsurefire.failIfNoSpecifiedTests=true -DforkCount=0 -Dspring.jpa.hibernate.ddl-auto=validate < /dev/null
|
||||
@@ -120,6 +120,10 @@ public class CallbackDispatcher {
|
||||
if (event.getData() != null) {
|
||||
data.putAll(event.getData());
|
||||
}
|
||||
// 身份在事件发布线程中冻结,不能用 AFTER_COMMIT 重读到的新轮给旧事件重新贴标。
|
||||
if (event.getRoundIdentity() != null) {
|
||||
data.putAll(event.getRoundIdentity());
|
||||
}
|
||||
payload.put("data", data);
|
||||
String payloadJson = objectMapper.writeValueAsString(payload);
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.yunhai.flowcenter.callback;
|
||||
|
||||
import com.yunhai.flowcenter.engine.FlowEvent;
|
||||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 同步发布阶段冻结轮次身份;不修改引擎或 apply/v2 七支分支。 */
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FlowEventIdentityListener {
|
||||
private final FlwInstanceRepository instances;
|
||||
|
||||
@EventListener
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public void capture(FlowEvent event) {
|
||||
instances.findById(event.getInstanceId()).ifPresent(instance ->
|
||||
event.captureRoundIdentity(instance.getApplyRound(), instance.getApplyRequestToken()));
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,15 @@ public class FlowEvent {
|
||||
private final String operatorName;
|
||||
/** 事件明细(result/opinion/rejectNode/task.created 的 n/m 等),可为空 */
|
||||
private final Map<String, Object> data;
|
||||
private Map<String, Object> roundIdentity;
|
||||
|
||||
public void captureRoundIdentity(Integer round, String requestToken) {
|
||||
if (roundIdentity != null) return;
|
||||
Map<String, Object> identity = new HashMap<>();
|
||||
identity.put("applyRound", round);
|
||||
identity.put("requestToken", requestToken);
|
||||
roundIdentity = java.util.Collections.unmodifiableMap(identity);
|
||||
}
|
||||
|
||||
public static FlowEvent of(Type type, Long instanceId) {
|
||||
return new FlowEvent(type, instanceId, null, null, null, new HashMap<>());
|
||||
|
||||
@@ -60,6 +60,9 @@ public final class FlowApplyRetryModels {
|
||||
private String branch;
|
||||
/** 行上的当前轮次(消费方据此校正自己的命令表认知) */
|
||||
private Integer applyRound;
|
||||
/** 同一响应的真实状态/实例版本;分支判据保持不变。 */
|
||||
private Integer status;
|
||||
private Integer version;
|
||||
}
|
||||
|
||||
/** 分支码常量(与 {@link ApplyResultV2#branch} 同值域) */
|
||||
|
||||
@@ -107,6 +107,8 @@ public final class OapiModels {
|
||||
@Data
|
||||
public static class InstanceVo {
|
||||
private Long instanceId;
|
||||
private Integer applyRound;
|
||||
private String requestToken;
|
||||
private Integer status;
|
||||
private Integer version;
|
||||
private String nodeSummary;
|
||||
|
||||
@@ -223,6 +223,15 @@ public class OapiFlowService {
|
||||
vo.setDuplicated(outcome.duplicated);
|
||||
vo.setBranch(outcome.branch);
|
||||
vo.setApplyRound(outcome.applyRound);
|
||||
instanceRepository.findById(outcome.instanceId).ifPresent(current -> {
|
||||
int currentRound = current.getApplyRound() == null ? 1 : current.getApplyRound();
|
||||
int outcomeRound = outcome.applyRound == null ? 1 : outcome.applyRound;
|
||||
if (currentRound == outcomeRound) {
|
||||
vo.setStatus(current.getStatus());
|
||||
vo.setVersion(current.getVersion());
|
||||
} // 已被另一请求推进到新轮时,让消费方按实例查询恢复,不混装两轮证据。
|
||||
|
||||
});
|
||||
return vo;
|
||||
}
|
||||
|
||||
@@ -252,6 +261,8 @@ public class OapiFlowService {
|
||||
vo.setInstanceId(existing.getId());
|
||||
vo.setDuplicated(true);
|
||||
vo.setApplyRound(existing.getApplyRound());
|
||||
vo.setStatus(existing.getStatus());
|
||||
vo.setVersion(existing.getVersion());
|
||||
vo.setBranch(token != null && token.equals(existing.getApplyRequestToken())
|
||||
? FlowApplyRetryModels.Branch.SAME_REQUEST : FlowApplyRetryModels.Branch.CONCURRENT_CREATED);
|
||||
log.warn("[flow-center] 并发建件命中既有实例:instance={} biz={}/{} branch={}",
|
||||
@@ -1112,6 +1123,8 @@ public class OapiFlowService {
|
||||
public OapiModels.InstanceVo toInstanceVo(FlwInstance instance) {
|
||||
OapiModels.InstanceVo vo = new OapiModels.InstanceVo();
|
||||
vo.setInstanceId(instance.getId());
|
||||
vo.setApplyRound(instance.getApplyRound());
|
||||
vo.setRequestToken(instance.getApplyRequestToken());
|
||||
vo.setStatus(instance.getStatus());
|
||||
vo.setVersion(instance.getVersion());
|
||||
vo.setBizTitle(instance.getBizTitle());
|
||||
|
||||
@@ -48,6 +48,9 @@ class OapiFlowTasksByBizTest extends FlowTestSupport {
|
||||
|
||||
private OapiSignedClient client;
|
||||
|
||||
@Autowired
|
||||
private javax.sql.DataSource dataSource;
|
||||
|
||||
@TestConfiguration
|
||||
static class StubConfig {
|
||||
@Bean
|
||||
@@ -58,7 +61,21 @@ class OapiFlowTasksByBizTest extends FlowTestSupport {
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
void setUp() throws Exception {
|
||||
// 在 cleanDb 之前验证真实连接,不能只相信环境变量已覆盖 profile。
|
||||
try (java.sql.Connection connection = dataSource.getConnection()) {
|
||||
String schema = connection.getCatalog();
|
||||
String host = java.net.URI.create(connection.getMetaData().getURL().substring(5)).getHost();
|
||||
System.out.println("CI_DB_TARGET=" + host + "/" + schema);
|
||||
assertTrue("127.0.0.1".equals(host) || "localhost".equals(host)
|
||||
|| (host != null && host.startsWith("mavenbuild-") && host.endsWith("-db")),
|
||||
"真库门禁只允许本机或本次 CI 容器");
|
||||
assertTrue("bsch_flowcenter_test".equals(schema) || "flowcenter_ci".equals(schema)
|
||||
|| (schema != null && schema.startsWith("flowcenter_ci_")), "拒绝清理非测试 schema");
|
||||
if (System.getenv("CI_TEST_DB_URL") != null) {
|
||||
assertTrue(schema.startsWith("flowcenter_ci"), "CI 必须实际连接独立 schema");
|
||||
}
|
||||
}
|
||||
cleanDb();
|
||||
client = new OapiSignedClient("http://localhost:" + port, APP_KEY, APP_SECRET);
|
||||
}
|
||||
|
||||
@@ -287,6 +287,35 @@ class FlApplyRecoveryTest {
|
||||
assertThat(existing.getApplyRound()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void callbackIdentityIsFrozenBeforeCommitAndNeverRelabelsOldEvent() throws Exception {
|
||||
FlwInstance row = instance(900L, 30, TOKEN_A, 1, "100018");
|
||||
row.setVersion(3);
|
||||
when(instanceRepository.findById(900L)).thenReturn(Optional.of(row));
|
||||
com.yunhai.flowcenter.engine.FlowEvent event = com.yunhai.flowcenter.engine.FlowEvent.of(
|
||||
com.yunhai.flowcenter.engine.FlowEvent.Type.REJECTED, 900L);
|
||||
new com.yunhai.flowcenter.callback.FlowEventIdentityListener(instanceRepository).capture(event);
|
||||
row.setApplyRound(2); row.setApplyRequestToken(TOKEN_B); row.setVersion(4);
|
||||
new com.yunhai.flowcenter.callback.FlowEventIdentityListener(instanceRepository).capture(event);
|
||||
assertThat(event.getRoundIdentity().get("applyRound")).isEqualTo(1);
|
||||
|
||||
com.yunhai.flowcenter.repository.FlwCallbackRegRepository regs = mock(com.yunhai.flowcenter.repository.FlwCallbackRegRepository.class);
|
||||
com.yunhai.flowcenter.callback.CallbackLogStore store = mock(com.yunhai.flowcenter.callback.CallbackLogStore.class);
|
||||
com.yunhai.flowcenter.entity.FlwCallbackReg reg = new com.yunhai.flowcenter.entity.FlwCallbackReg();
|
||||
reg.setId(7L);
|
||||
when(regs.findBySchIdAndFlowGuidAndStatus(SCH, FLOW_GUID, 0)).thenReturn(java.util.Collections.singletonList(reg));
|
||||
com.yunhai.flowcenter.callback.CallbackDispatcher dispatcher = new com.yunhai.flowcenter.callback.CallbackDispatcher(
|
||||
instanceRepository, defRepository, regs, mock(com.yunhai.flowcenter.repository.FlwCallbackLogRepository.class),
|
||||
store, mock(com.yunhai.flowcenter.callback.CallbackPushService.class), new com.yunhai.flowcenter.callback.CallbackProperties(), mapper);
|
||||
org.springframework.test.util.ReflectionTestUtils.setField(dispatcher, "pushExecutor", mock(java.util.concurrent.ExecutorService.class));
|
||||
dispatcher.onFlowEvent(event);
|
||||
ArgumentCaptor<com.yunhai.flowcenter.entity.FlwCallbackLog> log = ArgumentCaptor.forClass(com.yunhai.flowcenter.entity.FlwCallbackLog.class);
|
||||
verify(store).persist(log.capture());
|
||||
com.fasterxml.jackson.databind.JsonNode data = mapper.readTree(log.getValue().getPayloadJson()).get("data");
|
||||
assertThat(data.get("applyRound").asInt()).isEqualTo(1);
|
||||
assertThat(data.get("requestToken").asText()).isEqualTo(TOKEN_A);
|
||||
}
|
||||
|
||||
// ==================== 夹具 ====================
|
||||
|
||||
/** 提交者恒 1001、调用应用恒 100018;不符的一侧都在被测行上构造 */
|
||||
|
||||
@@ -47,6 +47,7 @@ class OapiFlowApplyDefVersionTest {
|
||||
private FlowInstanceService instanceService;
|
||||
private AssigneeResolver assigneeResolver;
|
||||
private OapiFlowService service;
|
||||
private FlwInstanceRepository instances;
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -54,7 +55,8 @@ class OapiFlowApplyDefVersionTest {
|
||||
defRepository = mock(FlwDefRepository.class);
|
||||
instanceService = mock(FlowInstanceService.class);
|
||||
assigneeResolver = mock(AssigneeResolver.class);
|
||||
service = new OapiFlowService(defRepository, mock(FlwInstanceRepository.class),
|
||||
instances = mock(FlwInstanceRepository.class);
|
||||
service = new OapiFlowService(defRepository, instances,
|
||||
mock(FlwTaskRepository.class), mock(FlwCcRepository.class),
|
||||
mock(FlwCallbackRegRepository.class), instanceService, mock(FlowTaskService.class),
|
||||
mock(FlowEngine.class), assigneeResolver, new ObjectMapper(),
|
||||
@@ -150,4 +152,20 @@ class OapiFlowApplyDefVersionTest {
|
||||
assertEquals(Integer.valueOf(1), vo.getDefVersion());
|
||||
assertTrue(vo.getNodes() == null || vo.getNodes().isEmpty());
|
||||
}
|
||||
@Test
|
||||
void v2ResponseCarriesRealRejectedStatusAndStableBranch() {
|
||||
stubDef(3);
|
||||
com.yunhai.flowcenter.model.FlowApplyRetryModels.ApplyRequestV2 body = new com.yunhai.flowcenter.model.FlowApplyRetryModels.ApplyRequestV2();
|
||||
body.setFlowGuid(FLOW_GUID); body.setBizType("svc-hall"); body.setBizId("42"); body.setSubmitterId(21);
|
||||
body.setRequestToken("token-1"); body.setAttempt(1);
|
||||
when(instanceService.applyGuarded(any(), any())).thenReturn(
|
||||
new FlowInstanceService.GuardedOutcome(500L, true, "SAME_REQUEST", 1));
|
||||
com.yunhai.flowcenter.entity.FlwInstance row = new com.yunhai.flowcenter.entity.FlwInstance();
|
||||
row.setId(500L); row.setStatus(30); row.setVersion(4); row.setApplyRound(1);
|
||||
when(instances.findById(500L)).thenReturn(Optional.of(row));
|
||||
com.yunhai.flowcenter.model.FlowApplyRetryModels.ApplyResultV2 result = service.applyV2(SCH_ID, "100009", body);
|
||||
assertEquals("SAME_REQUEST", result.getBranch()); assertEquals(Integer.valueOf(1), result.getApplyRound());
|
||||
assertEquals(Integer.valueOf(30), result.getStatus()); assertEquals(Integer.valueOf(4), result.getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user