注意事项
1、【重要】升级前备份base库和用户权限模块所在的库
2、【重要】升级过程执行SQL严格按照文档中写的顺序执行。特别注意:部分SQL是要求【发布前执行】,部分SQL是要求【发布后执行】
概述
该升级说明仅针对4.7.8以上版本,如正在使用4.7.8之前的版本,可根据升级说明尝试升级,或联系Oinone平台售后获取技术支持。
主要变动
- rocketmq配置方式变化
- 依赖变化
- yaml配置变化
- 用法发生变化
- 弃用canal监听binlog,改用sql-records模块
- 依赖变化
- yaml配置变化
- 权限
- 依赖变化
- 用法发生变化
- 需执行迁移脚本
- 翻译
- 需执行迁移脚本
- 集成设计器
- 需执行迁移脚本
重要事项
- 本次升级需停机发布,以确保升级过程可以稳健进行。
- 在升级前,停机后,需妥善备份数据库,以防止无法预知的问题无法正常上线。
- 强烈建议在测试环境先模拟升级步骤,并根据部署环境建立自己的升级步骤文档及升级执行记录,以确保生产环境可以稳定升级。
- 本次升级执行的记录应妥善保留一段时间,以确保线上环境出现无法预知问题时进行修复。
升级步骤
发布前确认
admin
用户或具备超级管理员的用户是否可以正常登录- 是否已创建升级步骤文档及升级执行记录文档
- 当前时段是否允许停机发布
1. 根据版本说明中提供的版本号进行修改
PS: 下列版本号为5.0.0版本的首个稳定版本,如需要更新到最新版本,请根据5.0.x版本的更新日志查看最新版本。
<!-- 平台基础 -->
<pamirs.middleware.version>5.0.0</pamirs.middleware.version>
<pamirs.k2.version>5.0.1</pamirs.k2.version>
<pamirs.framework.version>5.0.2</pamirs.framework.version>
<pamirs.boot.version>5.0.1</pamirs.boot.version>
<pamirs.distribution.version>5.0.1</pamirs.distribution.version>
<!-- 平台功能 -->
<pamirs.metadata.manager>5.0.0</pamirs.metadata.manager>
<pamirs.core.version>5.0.2</pamirs.core.version>
<pamirs.workflow.version>5.0.1</pamirs.workflow.version>
<pamirs.workbench.version>5.0.1</pamirs.workbench.version>
<pamirs.data.visualization.version>5.0.1</pamirs.data.visualization.version>
2. 所有项目工程修改依赖项
pamirs-auth-api
变更为pamirs-auth3-api
原依赖项:
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth-api</artifactId>
</dependency>
修改后的依赖项:
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth3-api</artifactId>
</dependency>
pamirs-auth-core
变更为pamirs-auth3-core
原依赖项:
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth-core</artifactId>
</dependency>
修改后的依赖项:
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth3-core</artifactId>
</dependency>
3. 启动工程添加依赖项
<!-- rocketmq -->
<dependency>
<groupId>pro.shushi.pamirs.framework</groupId>
<artifactId>pamirs-connectors-event-rocketmq</artifactId>
</dependency>
<!-- auth -->
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth3-core</artifactId>
</dependency>
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth3-view</artifactId>
</dependency>
<!-- auth compatible -->
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth-compatible</artifactId>
</dependency>
<!-- management center -->
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-management-center</artifactId>
</dependency>
<!-- sql-record -->
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-sql-record-core</artifactId>
</dependency>
其他可能需要补充的依赖项
- eip模块从core中分离出view部分代码,如有用到eip模块,则需要检查该依赖项
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-eip2-view</artifactId>
</dependency>
- 主POM依赖缺失可能会导致版本无法正确处理,如缺少以下依赖的,则需要补充缺失的版本管理依赖
<dependency>
<groupId>pro.shushi.pamirs</groupId>
<artifactId>pamirs-k2</artifactId>
<version>${pamirs.k2.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>pro.shushi.pamirs</groupId>
<artifactId>pamirs-framework</artifactId>
<version>${pamirs.framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>pro.shushi.pamirs.boot</groupId>
<artifactId>pamirs-boot-dependencies</artifactId>
<version>${pamirs.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-core-dependencies</artifactId>
<version>${pamirs.core.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>pro.shushi.pamirs</groupId>
<artifactId>pamirs-distribution</artifactId>
<version>${pamirs.distribution.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
4. 根据环境配置yaml
spring:
rocketmq:
name-server: 127.0.0.1:9876
#ACL配置
#accesskey: xxxx
#secretkey: xxx
pamirs:
boot:
modules:
- management_center
- sql_record
event:
notify-map:
system: ROCKETMQ
biz: ROCKETMQ
logger: ROCKETMQ
record:
sql:
# 修改为自己的环境路径,需提前创建可访问目录,镜像部署请使用镜像中可访问的路径
store: /opt/pamirs/logs/sql-records
被废弃的配置:
pamirs.event.rocket-mq
pamirs.auth.model-filter
5. 编译所有项目工程,解决依赖报错的问题
下面列出了部分已知需要修改的问题及解决方案:
- RocketMQ注册消费者方式发生变化,不修改的情况下会导致MQ无法正常消费
主要变更:NotifyEventListener
变更为NotifyConsumer<T>
// 原注册及使用方式
@Bean
@NotifyListener(topic = TEST_PRODUCTION_ORDER_EVENT_TOPIC, bodyClass = ProductionOrderScheduling.class)
public NotifyEventListener testProductionOrderEvent() {
return (event) -> {
ProductionOrderScheduling data = (ProductionOrderScheduling) event.getBody();
System.out.println(data.getName());
};
}
// 新注册及使用方式
@Bean
@NotifyListener(topic = TEST_PRODUCTION_ORDER_EVENT_TOPIC, bodyClass = ProductionOrderScheduling.class)
public NotifyConsumer<ProductionOrderScheduling> testProductionOrderEvent() {
return (event) -> {
ProductionOrderScheduling data = event.getPayload();
// do something.
};
}
-
权限初始化相关逻辑可以暂时注释,可以完全在页面上进行配置
-
获取当前角色可使用
AuthRoleSession#getCurrentRoles
方法 -
导入路径发生变化
// 原路径 import pro.shushi.pamirs.core.common.entry.TreeNode; // 新路径 import pro.shushi.pamirs.framework.common.entry.TreeNode;
-
创建用户时,密码不再使用PamirsUser中的密码配置,请独立使用PasswordService进行创建。
-
保存用户角色并差量更新缓存可以参考如下实现:
private void updateRolesAndRefresh(PamirsUser user, List<AuthRole> roles) {
Long userId = user.getId();
DiffSet<Long> diffRoles = authUserRoleDiffService.saveRoles(userId, roles);
if (diffRoles != null) {
authUserRoleDiffService.refreshUserRoles(userId, diffRoles);
}
}
-
ExcelExportFetchDataContext构造函数发生变更,第三个参数sheetDefinition传入即可。
-
通过代码方式实现的数据过滤可以参考如下实现进行处理:
@Order(0)
@Component
public class CustomAuthFilterService extends DefaultAuthFilterService implements AuthFilterService {
@Override
public AuthResult<String> fetchModelFilterForRead(String model) {
AuthResult<String> result = super.fetchModelFilterForRead(model);
if (PamirsUser.MODEL_MODEL.equals(model)) {
if (result.getData() == null) {
return AuthResult.success(generatorFilter());
}
return result.transfer(filter -> "(" + filter + ") and " + generatorFilter());
}
return result;
}
private String generatorFilter() {
return "source == " + UserSourceEnum.MANUAL.value();
}
}
6. 关闭用户访问(生产发布时必须)
7. 备份所有数据库的全部数据(停机后备份,以防止备份不完全)
8. 启动前执行SQL(逐行执行!!!)
- 元数据修复
-- 修复界面设计器菜单元数据注册表
insert into base_model_data(id, low_code, source, code, module, load_module, model, res_id, date_init,date_update,create_uid,write_uid) select id,1 as low_code,'UI' as source,concat('base.Menu#', module, '#', name) code, module, module as load_module, 'base.Menu' as model, id as res_id, DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') as date_init, DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') as date_update, '10001' as create_uid, '10001' as write_uid from base_menu where system_source = 'UI' and is_deleted = 0 and id not in (select res_id from base_model_data where res_id in (select id from base_menu where system_source = 'UI' and is_deleted = 0) and is_deleted = 0);
- 翻译数据修复
-- 修复历史数据
update resource_resource_translation_item as rrt SET is_deleted=rrt.id where module is NULL and is_deleted=0;
update resource_resource_translation_item as rrt SET module ='management_center' where module='auth' and is_deleted=0;
update resource_resource_translation_item as rrt SET module ='management_center' where module='business' and is_deleted=0;
update resource_resource_translation_item as rrt SET module ='management_center' where module='user' and is_deleted=0;
-- 删除重复历史数据
UPDATE resource_resource_translation_item AS rrt LEFT JOIN (SELECT MAX(id) AS max_id FROM resource_resource_translation_item GROUP BY module, origin_code, res_lang_code, lang_code,is_deleted) AS max_records ON rrt.id = max_records.max_id SET rrt.is_deleted = rrt.id WHERE max_records.max_id IS NULL;
-- 修改resource_resource_translation 的唯一键
ALTER TABLE resource_resource_translation DROP INDEX urce_resource_translation_module_model_res_lang_code_lang_code_d;
-- 移除无效历史数据
ALTER TABLE resource_resource_translation RENAME COLUMN model TO _d_model_888888;
-- 删除重复历史数据
UPDATE resource_resource_translation AS rrt LEFT JOIN (SELECT MAX(id) AS max_id FROM resource_resource_translation GROUP BY module, res_lang_code, lang_code,is_deleted) AS max_records ON rrt.id = max_records.max_id SET rrt.is_deleted = rrt.id WHERE max_records.max_id IS NULL;
9. 启动后端服务进行自动升级
10.启动后执行SQL( 逐行执行!!!)
- 用户/权限数据修复
-- 查询完成记录结果 U00001001
select code from user_pamirs_user where id = 10001;
-- 更新用户表
update user_pamirs_user set code = '10000' where id = 10000;
update user_pamirs_user set code = '10001' where id = 10001;
update user_pamirs_user set source = 'BUILD_IN' where id in (10000, 10001, 10086, 10088, 8848);
update user_pamirs_user set source = 'MANUAL' where source is null;
-- 迁移用户密码
insert into user_pamirs_password (id, user_id, `password`, initial_password) select id, id, `password`, initial_password from user_pamirs_user where is_deleted = 0 and id not in (select user_id from user_pamirs_password where is_deleted = 0);
-- 查询完成记录结果 336327172278978337
select id from auth_auth_role_type where code = 'SYSTEM';
-- 更新角色类型表(使用上面的记录替换where条件后的id)
update auth_auth_role_type set `name` = `type` where `name` is null;
update auth_auth_role_type set id = 10000, source = 'BUILD_IN' where id = 336327172278978337;
update auth_auth_role_type set source = 'MANUAL' where source is null;
update auth_auth_role set code = name where code is null or code = '' and is_deleted = 0;
-- 查询完成记录结果
-- id code
-- 336327172278978338 R00001
-- 441930750116663818 R00002
-- 336336715696312723 R00003
select id,code,name from auth_auth_role where code in ('R00001', 'R00002', 'R00003');
-- 更新角色表(使用上面的记录替换where条件后的id)
update auth_auth_role set id = 10001, source = 'BUILD_IN' where id = 336327172278978338;
update auth_auth_role set id = 10002, source = 'SYSTEM' where id = 441930750116663818;
update auth_auth_role set id = 10003, source = 'SYSTEM' where id = 336336715696312723;
update auth_auth_role set source = 'MANUAL' where source is null;
-- 更新用户角色关联表(使用上面的记录替换where条件后的id)
update auth_user_role_rel set role_id = 10001, source = 'BUILD_IN' where role_id = 336327172278978338;
update auth_user_role_rel set role_id = 10002, source = 'SYSTEM' where role_id = 441930750116663818;
update auth_user_role_rel set role_id = 10003, source = 'SYSTEM' where role_id = 336336715696312723;
update auth_user_role_rel set source = 'MANUAL' where source is null;
update auth_user_role_rel set active = true where active is null;
-- 更新权限组关联角色表(使用上面的记录替换where条件后的id)
update auth_auth_group_role_rel set auth_role_id = 10001 where auth_role_id = 336327172278978338;
update auth_auth_group_role_rel set auth_role_id = 10002 where auth_role_id = 441930750116663818;
update auth_auth_group_role_rel set auth_role_id = 10003 where auth_role_id = 336336715696312723;
-- 查询超级管理员组并记录结果 336336715696312731
select id from auth_auth_group where name = '超级管理员组';
-- 删除超级管理员组所有权限配置及权限项(使用上面的记录替换where条件后的id)
update auth_resource_permission set is_deleted = 1 where id in (select resource_permission_id from auth_auth_group_permission_rel where auth_group_id = 336336715696312731) and is_deleted = 0;
update auth_auth_group_permission_rel set is_deleted = 1 where auth_group_id = 336336715696312731 and is_deleted = 0;
update auth_auth_group set is_deleted = 1 where id = 336336715696312731 and is_deleted = 0;
update auth_auth_group_role_rel set is_deleted = 1 where auth_group_id = 336336715696312731 and is_deleted = 0;
update auth_auth_group_role_rel set is_deleted = 1 where auth_role_id not in (select id from auth_auth_role where is_deleted = 0);
update auth_auth_group_role_rel set is_deleted = 1 where auth_group_id not in (select id from auth_auth_group where is_deleted = 0);
update auth_auth_group_menu_rel set is_deleted = 1 where permission_id is null and is_deleted = 0;
- 翻译数据修复
UPDATE resource_resource_translation_item set scope='MODULE' where scope is null and is_deleted=0;
集成设计器数据修复
UPDATE designer_eip_connector_resource SET interface_name = id WHERE (interface_name IS NULL OR interface_name = '') AND is_deleted = 0;
11. 启用用户访问(如内外网分离的情况下,先启动内网访问即可)
PS: 如无旧版权限,或弃用旧版配置的权限,此步骤可省略
- 使用
admin
用户登录,并进入管理中心
模块。 - 选择
角色管理
菜单项,点击一键迁移旧版权限
。 - 观察后端服务日志,迁移过程可能耗费时间较长,不同环境配置的超时时间不同,可能导致接口超时,但后端服务仍在继续运行,请根据后端服务日志确定迁移过程是否完成。迁移过程请保证没有用户进行访问和操作。
- 当看到关键字
Auth migrate data cast time
时,表示权限数据已迁移完成。 - 所有旧版权限已完成迁移。
12. 移除权限兼容依赖(如与设计器公用base库,请忽略此步骤)
在启动工程中移除下列依赖:
<!-- auth compatible -->
<dependency>
<groupId>pro.shushi.pamirs.core</groupId>
<artifactId>pamirs-auth-compatible</artifactId>
</dependency>
13. 前端同步升级
前端打开package.json,把里面@kunlun/
开头的包的版本号,从~4.7.0
改为~5.0.0
,然后重新安装依赖
pc端按文档5.x前端升级事项处理好里面的变动内容
移动端按文档移动端5.0.x启动、打包代码报错处理好里面的变动内容
14. 升级完成
Congratulations!
升级常见问题
使用管理员登录后提示【未找到入口应用或无权限访问】
原因:未按照文档关闭用户访问,在修改数据库前有其他请求访问后端服务,导致缓存中的用户角色信息错误
解决方案:
使用命令清理redis中用户角色缓存即可。
创建redis-clear.sh
脚本,修改$host、$port、$pwd
等相关变量后,执行该脚本即可。
#!/bin/bash
$host=127.0.0.1
$port=6379
$pwd=Abc@1234
redis-cli -h $host -p $port -a "$pwd" --scan --pattern 'pamirs:auth:role:*' | xargs redis-cli -h $host -p $port -a "$pwd" del
脚本作用:连接指定redis服务端,扫描所有pamirs:auth:role:*
的匹配key,并全部删除。
进入翻译模块后显示【暂无首页,请联系管理员】
PS:其他模块若出现类似问题,也可使用该步骤尝试解决。
- 执行SQL脚本
update base_module set home_page_model = null, home_page_name = null where module = 'translate' and is_deleted = 0;
脚本作用:新版模块首页逻辑变更,原模块首页数据不再通过代码更新,因此需要手动置空home_page_model和home_page_name字段。默认将使用default_home_page_model和default_home_page_name查找首页。
- 执行redis命令
del base.Module:translate:module_module del base.Module:translate:module_name
脚本作用:新版模块数据不再通过数据库直接返回,而是优先通过redis缓存中的数据返回。删除指定元数据的redis缓存,运行时会重新从数据库将元数据写入redis缓存,从而达到缓存刷新的目的。
- 进入其他模块,刷新页面,再尝试进入翻译模块。
Oinone社区 作者:张博昊原创文章,如若转载,请注明出处:https://doc.oinone.top/version/11400.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验