您的位置:首页 > 编程语言 > Java开发

[Java][activiti]同步或者重构activiti identify用户数据的方法

2015-09-16 13:46 507 查看


同步或者重构Activiti Identify用户数据的多种方案比较

相信每个涉及到用户的系统都有一套用户权限管理平台或者模块,用来维护用户以及在系统内的功能、数据权限,我们使用的Activiti工作流引擎配套设计了包括User、Group的Identify模块,怎么和业务数据同步呢,这个问题是每个新人必问的问题之一,下面介绍几种同步方案,最后总结比较。
如果你在考虑直接使用Activiti引擎的Identify模块作为系统的用户数据管理模块,您真是奇才~开个玩笑

方案一:调用IdentifyService接口完成同步

参考IdentifyService接口Javadoc:http://www.activiti.org/javadocs/org/activiti/engine/IdentityService.html


接口定义:



[java] view
plaincopy

importjava.util.List;

importcom.foo.arch.entity.id.User;

importcom.foo.arch.service.ServiceException;

/**

* 维护用户、角色、权限接口

*

* @author HenryYan

*

*/

publicinterface AccountService {

/**

* 添加用户并[同步其他数据库]

* <ul>

* <li>step 1: 保存系统用户,同时设置和部门的关系</li>

* <li>step 2: 同步用户信息到activiti的identity.User,同时设置角色</li>

* </ul>

*

* @param user 用户对象

* @param orgId 部门ID

* @param roleIds 角色ID集合

* @param synToActiviti 是否同步到Activiti数据库,通过配置文件方式设置,使用属性:account.user.add.syntoactiviti

* @throws OrganizationNotFoundException 关联用户和部门的时候从数据库查询不到哦啊部门对象

* @throws Exception 其他未知异常

*/

publicvoid save(User user, Long orgId, List<long> roleIds, booleansynToActiviti)

throws OrganizationNotFoundException, ServiceException, Exception;

/**

* 删除用户

* @param userId 用户ID

* @param synToActiviti 是否同步到Activiti数据库,通过配置文件方式设置,使用属性:account.user.add.syntoactiviti

* @throws Exception

*/

publicvoid delete(Long userId, booleansynToActiviti) throwsServiceException, Exception;

/**

* 同步用户、角色数据到工作流

* @throws Exception

*/

publicvoid synAllUserAndRoleToActiviti() throwsException;

/**

* 删除工作流引擎Activiti的用户、角色以及关系

* @throws Exception

*/

publicvoid deleteAllActivitiIdentifyData() throwsException;

}

同步单个接口实现片段:

[java] view
plaincopy

@Service

@Transactional

publicclass AccountServiceImpl implementsAccountService {

/**

* 保存用户信息,并且同步用户信息到activiti的identity.User和identify.Group

* @param user 用户对象{@link User}

* @param roleIds 用户拥有的角色ID集合

* @param synToActiviti 是否同步数据到Activiti

* @see Role

*/

publicvoid saveUser(User user, List<long> roleIds, booleansynToActiviti) {

String userId = ObjectUtils.toString(user.getId());

// 保存系统用户

accountManager.saveEntity(user);

// 同步数据到Activiti Identify模块

if(synToActiviti) {

UserQuery userQuery = identityService.createUserQuery();

List<org.activiti.engine.identity.user> activitiUsers = userQuery.userId(userId).list();

if(activitiUsers.size() == 1) {

updateActivitiData(user, roleIds, activitiUsers.get(0));

}elseif (activitiUsers.size() > 1) {

String errorMsg = "发现重复用户:id="+ userId;

logger.error(errorMsg);

thrownew RuntimeException(errorMsg);

}else{

newActivitiUser(user, roleIds);

}

}

}

/**

* 添加工作流用户以及角色

* @param user 用户对象{@link User}

* @param roleIds 用户拥有的角色ID集合

*/

privatevoid newActivitiUser(User user, List<long> roleIds) {

String userId = user.getId().toString();

// 添加用户

saveActivitiUser(user);

// 添加membership

addMembershipToIdentify(roleIds, userId);

}

/**

* 添加一个用户到Activiti {@link org.activiti.engine.identity.User}

* @param user 用户对象, {@link User}

*/

privatevoid saveActivitiUser(User user) {

String userId = user.getId().toString();

org.activiti.engine.identity.User activitiUser = identityService.newUser(userId);

cloneAndSaveActivitiUser(user, activitiUser);

logger.debug("add activiti user: {}", ToStringBuilder.reflectionToString(activitiUser));

}

/**

* 添加Activiti Identify的用户于组关系

* @param roleIds 角色ID集合

* @param userId 用户ID

*/

privatevoid addMembershipToIdentify(List<long> roleIds, String userId) {

for(Long roleId : roleIds) {

Role role = roleManager.getEntity(roleId);

logger.debug("add role to activit: {}", role);

identityService.createMembership(userId, role.getEnName());

}

}

/**

* 更新工作流用户以及角色

* @param user 用户对象{@link User}

* @param roleIds 用户拥有的角色ID集合

* @param activitiUser Activiti引擎的用户对象,{@link org.activiti.engine.identity.User}

*/

privatevoid updateActivitiData(User user, List<long> roleIds, org.activiti.engine.identity.User activitiUser) {

String userId = user.getId().toString();

// 更新用户主体信息

cloneAndSaveActivitiUser(user, activitiUser);

// 删除用户的membership

List<group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();

for(Group group : activitiGroups) {

logger.debug("delete group from activit: {}", ToStringBuilder.reflectionToString(group));

identityService.deleteMembership(userId, group.getId());

}

// 添加membership

addMembershipToIdentify(roleIds, userId);

}

/**

* 使用系统用户对象属性设置到Activiti User对象中

* @param user 系统用户对象

* @param activitiUser Activiti User

*/

privatevoid cloneAndSaveActivitiUser(User user, org.activiti.engine.identity.User activitiUser) {

activitiUser.setFirstName(user.getName());

activitiUser.setLastName(StringUtils.EMPTY);

activitiUser.setPassword(StringUtils.EMPTY);

activitiUser.setEmail(user.getEmail());

identityService.saveUser(activitiUser);

}

@Override

publicvoid delete(Long userId, booleansynToActiviti, booleansynToChecking) throwsServiceException, Exception {

// 查询需要删除的用户对象

User user = accountManager.getEntity(userId);

if(user == null) {

thrownew ServiceException("删除用户时,找不到ID为"+ userId + "的用户");

}

/**

* 同步删除Activiti User Group

*/

if(synToActiviti) {

// 同步删除Activiti User

List<role> roleList = user.getRoleList();

for(Role role : roleList) {

identityService.deleteMembership(userId.toString(), role.getEnName());

}

// 同步删除Activiti User

identityService.deleteUser(userId.toString());

}

// 删除本系统用户

accountManager.deleteUser(userId);

// 删除考勤机用户

if(synToChecking) {

checkingAccountManager.deleteEntity(userId);

}

}

}

同步全部数据接口实现片段:

同步全部数据步骤:

删除Activiti的User、Group、Membership数据

复制Role对象数据到Group

复制用户数据以及Membership数据

ActivitiIdentifyCommonDao.java

[java] view
plaincopy

publicclass ActivitiIdentifyCommonDao {

protectedLogger logger = LoggerFactory.getLogger(getClass());

@Autowired

privateJdbcTemplate jdbcTemplate;

/**

* 删除用户和组的关系

*/

publicvoid deleteAllUser() {

String sql = "delete from ACT_ID_USER";

jdbcTemplate.execute(sql);

logger.debug("deleted from activiti user.");

}

/**

* 删除用户和组的关系

*/

publicvoid deleteAllRole() {

String sql = "delete from ACT_ID_GROUP";

jdbcTemplate.execute(sql);

logger.debug("deleted from activiti group.");

}

/**

* 删除用户和组的关系

*/

publicvoid deleteAllMemerShip() {

String sql = "delete from ACT_ID_MEMBERSHIP";

jdbcTemplate.execute(sql);

logger.debug("deleted from activiti membership.");

}

}

ActivitiIdentifyService.java

[java] view
plaincopy

publicclass ActivitiIdentifyService extendsAbstractBaseService {

@Autowired

protectedActivitiIdentifyCommonDao activitiIdentifyCommonDao;

/**

* 删除用户和组的关系

*/

publicvoid deleteAllUser() {

activitiIdentifyCommonDao.deleteAllUser();

}

/**

* 删除用户和组的关系

*/

publicvoid deleteAllRole() {

activitiIdentifyCommonDao.deleteAllRole();

}

/**

* 删除用户和组的关系

*/

publicvoid deleteAllMemerShip() {

activitiIdentifyCommonDao.deleteAllMemerShip();

}

}

AccountServiceImpl.java

[java] view
plaincopy

publicclass AccountServiceImpl implementsAccountService {

@Override

publicvoid synAllUserAndRoleToActiviti() throwsException {

// 清空工作流用户、角色以及关系

deleteAllActivitiIdentifyData();

// 复制角色数据

synRoleToActiviti();

// 复制用户以及关系数据

synUserWithRoleToActiviti();

}

/**

* 复制用户以及关系数据

*/

privatevoid synUserWithRoleToActiviti() {

List<user> allUser = accountManager.getAll();

for(User user : allUser) {

String userId = user.getId().toString();

// 添加一个用户到Activiti

saveActivitiUser(user);

// 角色和用户的关系

List<role> roleList = user.getRoleList();

for(Role role : roleList) {

identityService.createMembership(userId, role.getEnName());

logger.debug("add membership {user: {}, role: {}}", userId, role.getEnName());

}

}

}

/**

* 同步所有角色数据到{@link Group}

*/

privatevoid synRoleToActiviti() {

List<role> allRole = roleManager.getAll();

for(Role role : allRole) {

String groupId = role.getEnName().toString();

Group group = identityService.newGroup(groupId);

group.setName(role.getName());

group.setType(role.getType());

identityService.saveGroup(group);

}

}

@Override

publicvoid deleteAllActivitiIdentifyData() throwsException {

activitiIdentifyService.deleteAllMemerShip();

activitiIdentifyService.deleteAllRole();

activitiIdentifyService.deleteAllUser();

}

}

方案二:覆盖IdentifyService接口的实现

此方法覆盖IdentifyService接口的默认实现类:org.activiti.engine.impl.IdentityServiceImpl

读者可以根据现有的用户管理接口实现覆盖IdentityServiceImpl的每个方法的默认实现,这样就等于放弃使用系列表:ACT_ID_。

此方法不再提供代码,请读者自行根据现有接口逐一实现接口定义的功能。

方案三:用视图覆盖同名的ACT_ID_系列表

此方案和第二种类似,放弃使用系列表:ACT_ID_,创建同名的视图。


1.删除已创建的ACT_ID_*表

创建视图必须删除引擎自动创建的ACT_ID_*表,否则不能创建视图。


2.创建视图:

ACT_ID_GROUP
ACT_ID_INFO
ACT_ID_MEMBERSHIP
ACT_ID_USER

创建的视图要保证数据类型一致,例如用户的ACT_ID_MEMBERSHIP表的两个字段都是字符型,一般系统中都是用NUMBER作为用户、角色的主键类型,所以创建视图的时候要把数字类型转换为字符型。


3.修改引擎默认配置

在引擎配置中设置属性dbIdentityUsedfalse即可。

[html] view
plaincopy

<beanidbeanid="processEngineConfiguration"class="org.activiti.spring.SpringProcessEngineConfiguration">

...

<propertynamepropertyname="dbIdentityUsed"ref="false">

...

</property></bean>

总结

方案:不破坏、不修改源码,面向接口编程推荐

方案:放弃原有的Identify模块,使用自定义的实现,特殊情况可以使用此方式;

方案:不需要编写Java代码,只需要创建同名视图即可,对于现有系统的集成、强烈推荐
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: