Statement: Activiti Version 5.22.0. act_id_* series tables related to users and user groups are generated when Activiti is initialized, but in actual business, our system may not access workflow in the initial stage. Later access involves how to connect users in existing business tables with Activiti. This paper briefly introduces the ideas below.
1. Custom Implementation of Activiti User Management Interface
The custom class CustomUserEntityManagerFactory implements the SessionFactory interface and overrides the getSessionType and openSession methods. The core code is as follows:
import org.activiti.engine.impl.interceptor.Session; import org.activiti.engine.impl.interceptor.SessionFactory; import org.activiti.engine.impl.persistence.entity.UserIdentityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CustomUserEntityManagerFactory implements SessionFactory{ @Autowired private CustomUserEntityManager customUserEntityManager; @Override public Class<?> getSessionType() { return UserIdentityManager.class; } @Override public Session openSession() { return customUserEntityManager; } }
Where the class CustomUserEntityManager inherits the UserEntityManager class:
import java.util.ArrayList; import java.util.List; import java.util.Map; import org.activiti.engine.identity.Group; import org.activiti.engine.impl.Page; import org.activiti.engine.impl.UserQueryImpl; import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity; import org.activiti.engine.impl.persistence.entity.UserEntity; import org.activiti.engine.impl.persistence.entity.UserEntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import com.fengunion.scf.data.usermanage.role.service.RoleService; import com.fengunion.scf.data.usermanage.user.entity.User; import com.fengunion.scf.data.usermanage.user.service.UserService; import com.fengunion.scf.data.workflow.common.constant.WorkflowConstants; import com.fengunion.scf.data.workflow.common.util.ActivitiUserUtil; @Component public class CustomUserEntityManager extends UserEntityManager{ @Autowired @Lazy private UserService userService; @Autowired @Lazy private RoleService roleService; @Override public UserEntity findUserById(String userId) { User user = getUser(userId); return ActivitiUserUtil.toActivitiUser(user); } @Override public List<Group> findGroupsByUser(String userId) { if (userId == null) { return null; } User uparam = new User(); uparam.setPkid(Long.valueOf(userId)); User user = userService.selectOne(uparam); List<String> list = roleService.fingRoleCodeByUserId(Long.valueOf(userId)); List<Group> gs = ActivitiUserUtil.toActivitiGroups(user.getFkEnterpriseBasicId(),list); return gs; } @Override public List<org.activiti.engine.identity.User> findUserByQueryCriteria(UserQueryImpl query, Page page) { User user = getUser(query.getId()); List<org.activiti.engine.identity.User> list = new ArrayList<>(); list.add(ActivitiUserUtil.toActivitiUser(user)); return list; } private User getUser(String userId) { User user = new User(); if(WorkflowConstants.INTERFACE_SYSTEM_ID.equals(userId)) { user.setPkid(Long.valueOf(WorkflowConstants.INTERFACE_SYSTEM_ID)); user.setNickName(WorkflowConstants.INTERFACE_SYSTEM_NAME); user.setRealName(WorkflowConstants.INTERFACE_SYSTEM_NAME); user.setPswd(""); user.setEmail(""); }else { User prarmUser = new User(); prarmUser.setPkid(Long.valueOf(userId)); user = userService.selectOne(prarmUser); } return user; } @Override public long findUserCountByQueryCriteria(UserQueryImpl query) { throw new RuntimeException("not implement method."); } @Override public IdentityInfoEntity findUserInfoByUserIdAndKey(String userId, String key) { throw new RuntimeException("not implement method."); } @Override public List<String> findUserInfoKeysByUserIdAndType(String userId, String type) { throw new RuntimeException("not implement method."); } @Override public List<org.activiti.engine.identity.User> findPotentialStarterUsers(String proceDefId) { throw new RuntimeException("not implement method."); } @Override public List<org.activiti.engine.identity.User> findUsersByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) { throw new RuntimeException("not implement method."); } @Override public long findUserCountByNativeQuery(Map<String, Object> parameterMap) { throw new RuntimeException("not implement method."); } }
2. Custom Implementation of Activiti User Management Interface
Custom class CustomGroupEntityManagerFactory implements SessionFactory interface, rewrites getSessionType and openSession methods, and the core code is as follows:
import org.activiti.engine.impl.interceptor.Session; import org.activiti.engine.impl.interceptor.SessionFactory; import org.activiti.engine.impl.persistence.entity.GroupIdentityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CustomGroupEntityManagerFactory implements SessionFactory{ @Autowired private CustomGroupEntityManager customGroupEntityManager; @Override public Class<?> getSessionType() { return GroupIdentityManager.class; } @Override public Session openSession() { return customGroupEntityManager; } }
Among them, the CustomGroupEntityManager class is as follows:
import java.util.List; import java.util.Map; import org.activiti.engine.identity.Group; import org.activiti.engine.impl.GroupQueryImpl; import org.activiti.engine.impl.Page; import org.activiti.engine.impl.persistence.entity.GroupEntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Component; import com.fengunion.scf.data.usermanage.role.service.RoleService; import com.fengunion.scf.data.usermanage.user.entity.User; import com.fengunion.scf.data.usermanage.user.service.UserService; import com.fengunion.scf.data.workflow.common.util.ActivitiUserUtil; @Component public class CustomGroupEntityManager extends GroupEntityManager{ @Lazy @Autowired private RoleService roleService; @Lazy @Autowired private UserService userService; @Override public List<Group> findGroupsByUser(String userId) { if (userId == null){ return null; } try { User uparam = new User(); uparam.setPkid(Long.valueOf(userId)); User user = userService.selectOne(uparam); List<String> list = roleService.fingRoleCodeByUserId(Long.valueOf(userId)); List<Group> gs = ActivitiUserUtil.toActivitiGroups(user.getFkEnterpriseBasicId(),list); return gs; } catch (EmptyResultDataAccessException e) { return null; } } @Override public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) { throw new RuntimeException("not implement method."); } @Override public long findGroupCountByQueryCriteria(GroupQueryImpl query) { throw new RuntimeException("not implement method."); } @Override public List<Group> findGroupsByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) { throw new RuntimeException("not implement method."); } @Override public long findGroupCountByNativeQuery(Map<String, Object> parameterMap) { throw new RuntimeException("not implement method."); } }
3. Register the user and user group management classes defined by yourself in the Activiti configuration. The core code is as follows (I take spring boot configuration as an example):
... @Autowired private CustomUserEntityManagerFactory customUserEntityManagerFactory; @Autowired private CustomGroupEntityManagerFactory customGroupEntityManagerFactory; ... @Override public void configure(SpringProcessEngineConfiguration processEngineConfiguration) { ... //Custom Users and Groups List<SessionFactory> customSessionFactories = new ArrayList<>(); customSessionFactories.add(customUserEntityManagerFactory); customSessionFactories.add(customGroupEntityManagerFactory); processEngineConfiguration.setCustomSessionFactories(customSessionFactories); ... }
The ActivitiUserUtil tool class is as follows:
import java.util.ArrayList; import java.util.List; import org.activiti.engine.identity.Group; import org.activiti.engine.impl.persistence.entity.GroupEntity; import org.activiti.engine.impl.persistence.entity.UserEntity; import com.fengunion.scf.data.usermanage.user.entity.User; public class ActivitiUserUtil { public static UserEntity toActivitiUser(User bUser){ UserEntity userEntity = new UserEntity(); userEntity.setId(bUser.getPkid().toString()); userEntity.setFirstName(bUser.getNickName()); userEntity.setLastName(bUser.getRealName()); userEntity.setPassword(bUser.getPswd()); userEntity.setEmail(bUser.getEmail()); userEntity.setRevision(1); return userEntity; } public static GroupEntity toActivitiGroup(Long enterpriseBasicId,String code){ GroupEntity groupEntity = new GroupEntity(); groupEntity.setRevision(1); groupEntity.setType("assignment"); groupEntity.setId(enterpriseBasicId+"_"+code); return groupEntity; } public static List<Group> toActivitiGroups(Long enterpriseBasicId,List<String> roleCodeList){ List<Group> groups = new ArrayList<>(); for (String code : roleCodeList) { GroupEntity groupEntity = toActivitiGroup(enterpriseBasicId,code); groups.add(groupEntity); } return groups; } }
So far, the implementation of custom users and user groups is basically achieved.