工作流迁移:由Activiti6.0转Camunda7.8填坑之路


前言

在十年前刚开始接触工作流引擎的时候,所知道的就只有Activiti,根本不知道还有没有其他工作流引擎,虽然中文手册和教程十分欠缺,但经过不断摸索,用得越来越顺,也一直用得好好的。最近在搭建一个工作流服务平台,找了很多前端画流程的开源框架,一直没找到Activiti专属的画图框架,后来找到了bpmn-js,但是发现画出来的流程在Activiti上跑不了,查了下才发现所使用的面板插件是Camunda专属的,其实连bpmn-js都是Camunda社区所开发的。顿时对Camunda产生的兴趣,在网上看了很多Camunda、Flowable、Activiti对比的文章,发现现在Camunda的社区是最活跃的,抱着尝试一下的想法,在项目上拉了个分支,开始了Camunda迁移工作。

 

为什么是Camunda7.8?

当前最新的版本其实是Camunda7.11,功能已经做得非常完善了,可以在maven库中找了官方的rest接口库、webapp库,再配合bpmn-js,根本不用怎么写代码就可以实现工作流管理。但是项目部署后根本启动不了,才知道跟springboot版本不兼容,我用的是springboot1.5.9,而camunda7.8以上版本都是基于springboot2.0的,所以只能使用7.8版本。

贴一下我的pom.xml



  4.0.0cn.jia
  jia-api-admin
  1.0.0
  jarjia-api-admin
  Jia服务平台管理后台
    org.springframework.boot
    spring-boot-starter-parent
    1.5.9.RELEASE
     
  
    UTF-8
    UTF-8
    1.8
    Edgware.SR3
  
    
      org.springframework.boot
      spring-boot-starter-data-redis
    
    
      org.springframework.session
      spring-session-data-redis
    
    
      org.springframework.boot
      spring-boot-starter-web
    
    
      org.springframework.boot
      spring-boot-configuration-processor
      true
      
        
          com.vaadin.external.google
          android-json
        
      
    
    
      org.springframework.boot
      spring-boot-starter-security
    
    
      org.springframework.security.oauth
            spring-security-oauth2
    
    
    
      org.camunda.bpm.springboot
      camunda-bpm-spring-boot-starter
      2.3.0
    
    
      org.mybatis.spring.boot
      mybatis-spring-boot-starter
      1.3.1
    
    
      com.github.pagehelper
      pagehelper-spring-boot-starter
      1.1.1
    
    
      mysql
      mysql-connector-java
      runtime
    
    
      com.alibaba
      druid
      1.1.6
    
    
      org.springframework.boot
      spring-boot-starter-test
      test
      
        
          com.vaadin.external.google
          android-json
        
      
    
    
      org.springframework.boot
      spring-boot-starter-tomcat
      
    
    
      org.springframework.boot
      spring-boot-devtools
      true
    
    
      org.projectlombok
      lombok
      provided
    
    
    
      org.json
      json
    
  
    
      nexus-snapshots
      http://maven.wydiy.com/repository/maven-snapshots/
    
    
      nexus-releases
      http://maven.wydiy.com/repository/maven-releases/
    
  
    jia-api-admin
    
      
        org.springframework.boot
        spring-boot-maven-plugin
      
      
        org.apache.maven.plugins
        maven-surefire-plugin
        
          true
        
      
    
  

 

数据库迁移

其实网上已经有迁移的教程,Camunda官网也提供的迁移的方法和脚本,但是那个是从Activiti5.21迁移到Camunda7.5,只能一边尝试一边解决版本问题。首先是数据库的迁移,如果是全新的项目,那什么都不用管,项目启动时就会自动新建表,但我原来使用的是Activiti6.0,已经有业务数据了,只能无缝迁移,还好Camunda是从Activiti分出来了,保留了Activiti的大部分表,结构也很相似,并且Camunda在github上也放了迁移脚本。我找到mysql的脚本,发现mysql的脚本居然有语法错误,只好自己修复一下,同时把脚本push都github上,本来没想过作者会留意,因为最后一次更新已经是三年前了,谁想作者竟然亲自问我push的理由,我说明理由后,把我的脚本merge到master上,真的是惊喜,作者也是一个很负责任的人。但是,那样还不够,7.8版本跟7.5版本还是有不少区别,没办法,只能拿我的库和7.8的初始化库一项一项地对比,整理出最新的脚本。

create table ACT_RU_INCIDENT (
  ID_ varchar(64) not null,
  INCIDENT_TIMESTAMP_ timestamp not null,
  INCIDENT_MSG_ varchar(4000),
  INCIDENT_TYPE_ varchar(255) not null,
  EXECUTION_ID_ varchar(64),
  ACTIVITY_ID_ varchar(255),
  PROC_INST_ID_ varchar(64),
  PROC_DEF_ID_ varchar(64),
  CAUSE_INCIDENT_ID_ varchar(64),
  ROOT_CAUSE_INCIDENT_ID_ varchar(64),
  CONFIGURATION_ varchar(255),
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create index ACT_IDX_INC_CONFIGURATION on ACT_RU_INCIDENT(CONFIGURATION_);
​
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_EXE
    foreign key (EXECUTION_ID_)
    references ACT_RU_EXECUTION (ID_);
​
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_PROCINST
    foreign key (PROC_INST_ID_)
    references ACT_RU_EXECUTION (ID_);
​
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_PROCDEF
    foreign key (PROC_DEF_ID_)
    references ACT_RE_PROCDEF (ID_);
​
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_CAUSE
    foreign key (CAUSE_INCIDENT_ID_)
    references ACT_RU_INCIDENT (ID_) on delete cascade on update cascade;
​
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_RCAUSE
    foreign key (ROOT_CAUSE_INCIDENT_ID_)
    references ACT_RU_INCIDENT (ID_) on delete cascade on update cascade;
​
​
​
/** add ACT_INST_ID_ column to execution table */
alter table ACT_RU_EXECUTION
    add ACT_INST_ID_ nvarchar(64);
​
​
/** populate ACT_INST_ID_ from history */
​
/** get from history for active activity instances */
UPDATE
    ACT_RU_EXECUTION E
SET
    ACT_INST_ID_  = (
        SELECT
            MAX(ID_)
        FROM
            ACT_HI_ACTINST HAI
        WHERE
            HAI.EXECUTION_ID_ = E.ID_
        AND
            HAI.END_TIME_ is null
    )
WHERE
    E.ACT_INST_ID_ is null
AND
    E.ACT_ID_ is not null;
​
/** remaining executions use execution id as activity instance id */
UPDATE
    ACT_RU_EXECUTION
SET
    ACT_INST_ID_  = ID_
WHERE
    ACT_INST_ID_ is null;
​
/** add SUSPENSION_STATE_ column to task table */
-- alter table ACT_RU_TASK
--    add SUSPENSION_STATE_ integer;
​
UPDATE ACT_RU_TASK T
INNER JOIN ACT_RU_EXECUTION E
  ON T.EXECUTION_ID_ = E.ID_
SET T.SUSPENSION_STATE_ = E.SUSPENSION_STATE_;
​
UPDATE ACT_RU_TASK
SET SUSPENSION_STATE_ = 1
WHERE SUSPENSION_STATE_ is null;
​
/** add authorizations **/
​
create table ACT_RU_AUTHORIZATION (
  ID_ varchar(64) not null,
  REV_ integer not null,
  TYPE_ integer not null,
  GROUP_ID_ varchar(255),
  USER_ID_ varchar(255),
  RESOURCE_TYPE_ integer not null,
  RESOURCE_ID_ varchar(64),
  PERMS_ integer,
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
alter table ACT_RU_AUTHORIZATION
    add constraint ACT_UNIQ_AUTH_USER
    unique (USER_ID_,TYPE_,RESOURCE_TYPE_,RESOURCE_ID_);
​
alter table ACT_RU_AUTHORIZATION
    add constraint ACT_UNIQ_AUTH_GROUP
    unique (GROUP_ID_,TYPE_,RESOURCE_TYPE_,RESOURCE_ID_);
​
/** add deployment ID to job table  **/
alter table ACT_RU_JOB
    add DEPLOYMENT_ID_ varchar(64);
​
/** add parent act inst ID */
alter table ACT_HI_ACTINST
    add PARENT_ACT_INST_ID_ varchar(64);-- add new column to historic activity instance table --
alter table ACT_HI_ACTINST
    add ACT_INST_STATE_ integer;
​
-- add follow-up date to tasks --
alter table ACT_RU_TASK
    add FOLLOW_UP_DATE_ datetime;
alter table ACT_HI_TASKINST
    add FOLLOW_UP_DATE_ datetime;
​
-- add JOBDEF table --
create table ACT_RU_JOBDEF (
    ID_ varchar(64) NOT NULL,
    REV_ integer,
    PROC_DEF_ID_ varchar(64) NOT NULL,
    PROC_DEF_KEY_ varchar(255) NOT NULL,
    ACT_ID_ varchar(255) NOT NULL,
    JOB_TYPE_ varchar(255) NOT NULL,
    JOB_CONFIGURATION_ varchar(255),
    SUSPENSION_STATE_ integer,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- add new columns to job table --
alter table ACT_RU_JOB
    add PROCESS_DEF_ID_ varchar(64);
​
alter table ACT_RU_JOB
    add PROCESS_DEF_KEY_ varchar(64);
​
alter table ACT_RU_JOB
    add SUSPENSION_STATE_ integer;
​
alter table ACT_RU_JOB
    add JOB_DEF_ID_ varchar(64);
​
-- update job table with values from execution table --
​
UPDATE
    ACT_RU_JOB J
SET
    PROCESS_DEF_ID_  = (
        SELECT
            PI.PROC_DEF_ID_
        FROM
            ACT_RU_EXECUTION PI
        WHERE
            PI.ID_ = J.PROCESS_INSTANCE_ID_
    ),
    SUSPENSION_STATE_  = (
        SELECT
            PI.SUSPENSION_STATE_
        FROM
            ACT_RU_EXECUTION PI
        WHERE
            PI.ID_ = J.PROCESS_INSTANCE_ID_
    );
​
UPDATE
    ACT_RU_JOB J
SET
    PROCESS_DEF_KEY_  = (
        SELECT
            PD.KEY_
        FROM
            ACT_RE_PROCDEF PD
        WHERE
            PD.ID_ = J.PROCESS_DEF_ID_
    );
​
-- add Hist OP Log table --
​
create table ACT_HI_OP_LOG (
    ID_ varchar(64) not null,
    PROC_DEF_ID_ varchar(64),
    PROC_INST_ID_ varchar(64),
    EXECUTION_ID_ varchar(64),
    TASK_ID_ varchar(64),
    USER_ID_ varchar(255),
    TIMESTAMP_ timestamp not null,
    OPERATION_TYPE_ varchar(64),
    OPERATION_ID_ varchar(64),
    ENTITY_TYPE_ varchar(30),
    PROPERTY_ varchar(64),
    ORG_VALUE_ varchar(4000),
    NEW_VALUE_ varchar(4000),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- add new column to ACT_HI_VARINST --
​
alter table ACT_HI_VARINST
    add ACT_INST_ID_ varchar(64);
​
alter table ACT_HI_DETAIL
    add VAR_INST_ID_ varchar(64);
​
alter table ACT_HI_TASKINST
    add ACT_INST_ID_ varchar(64);
​
-- set cached entity state to 63 on all executions --
​
UPDATE
    ACT_RU_EXECUTION
SET
    CACHED_ENT_STATE_ = 63;
​
-- add new table ACT_HI_INCIDENT --
​
create table ACT_HI_INCIDENT (
  ID_ varchar(64) not null,
  PROC_DEF_ID_ varchar(64),
  PROC_INST_ID_ varchar(64),
  EXECUTION_ID_ varchar(64),
  CREATE_TIME_ timestamp not null,
  END_TIME_ timestamp null,
  INCIDENT_MSG_ varchar(4000),
  INCIDENT_TYPE_ varchar(255) not null,
  ACTIVITY_ID_ varchar(255),
  CAUSE_INCIDENT_ID_ varchar(64),
  ROOT_CAUSE_INCIDENT_ID_ varchar(64),
  CONFIGURATION_ varchar(255),
  INCIDENT_STATE_ integer,
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- update ACT_RU_VARIABLE table --
​
-- add new column --
​
ALTER TABLE ACT_RU_VARIABLE
    add VAR_SCOPE_ varchar(64);
​
-- migrate execution variables --
​
UPDATE
  ACT_RU_VARIABLE V
​
SET
  VAR_SCOPE_ = V.EXECUTION_ID_
​
WHERE
  V.EXECUTION_ID_ is not null AND
  V.TASK_ID_ is null;
​
-- migrate task variables --
​
UPDATE
  ACT_RU_VARIABLE V
​
SET
  VAR_SCOPE_ = V.TASK_ID_
​
WHERE
  V.TASK_ID_ is not null;
​
-- set VAR_SCOPE_ not null --
​
ALTER TABLE ACT_RU_VARIABLE
    MODIFY VAR_SCOPE_ varchar(64) NOT NULL;
​
-- add unique constraint --
ALTER TABLE ACT_RU_VARIABLE
    ADD CONSTRAINT ACT_UNIQ_VARIABLE
    UNIQUE (VAR_SCOPE_, NAME_);
-- indexes for deadlock problems - https://app.camunda.com/jira/browse/CAM-2567 --
create index ACT_IDX_INC_CAUSEINCID on ACT_RU_INCIDENT(CAUSE_INCIDENT_ID_);
create index ACT_IDX_INC_EXID on ACT_RU_INCIDENT(EXECUTION_ID_);
create index ACT_IDX_INC_PROCDEFID on ACT_RU_INCIDENT(PROC_DEF_ID_);
create index ACT_IDX_INC_PROCINSTID on ACT_RU_INCIDENT(PROC_INST_ID_);
create index ACT_IDX_INC_ROOTCAUSEINCID on ACT_RU_INCIDENT(ROOT_CAUSE_INCIDENT_ID_);-- add deployment.lock row to property table --
INSERT INTO ACT_GE_PROPERTY
  VALUES ('deployment.lock', '0', 1);
​
-- add revision column to incident table --
ALTER TABLE ACT_RU_INCIDENT
  ADD REV_ INTEGER;
​
-- set initial incident revision to 1 --
UPDATE
  ACT_RU_INCIDENT
SET
  REV_ = 1;
​
-- set incident revision column to not null --
ALTER TABLE ACT_RU_INCIDENT
  MODIFY REV_ INTEGER NOT NULL;
​
-- case management
​
ALTER TABLE ACT_RU_VARIABLE
  ADD CASE_EXECUTION_ID_ varchar(64);
​
ALTER TABLE ACT_RU_VARIABLE
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_RU_TASK
  ADD CASE_EXECUTION_ID_ varchar(64);
​
ALTER TABLE ACT_RU_TASK
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_RU_TASK
  ADD CASE_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_RU_EXECUTION
  ADD SUPER_CASE_EXEC_ varchar(64);
​
ALTER TABLE ACT_RU_EXECUTION
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD CASE_EXECUTION_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD CASE_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_PROCINST
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_HI_TASKINST
  ADD CASE_EXECUTION_ID_ varchar(64);
​
ALTER TABLE ACT_HI_TASKINST
  ADD CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_HI_TASKINST
  ADD CASE_DEF_ID_ varchar(64);
​
-- create case definition table --
create table ACT_RE_CASE_DEF (
    ID_ varchar(64) not null,
    REV_ integer,
    CATEGORY_ varchar(255),
    NAME_ varchar(255),
    KEY_ varchar(255) not null,
    VERSION_ integer not null,
    DEPLOYMENT_ID_ varchar(64),
    RESOURCE_NAME_ varchar(4000),
    DGRM_RESOURCE_NAME_ varchar(4000),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create case execution table --
create table ACT_RU_CASE_EXECUTION (
    ID_ varchar(64) NOT NULL,
    REV_ integer,
    CASE_INST_ID_ varchar(64),
    SUPER_CASE_EXEC_ varchar(64),
    BUSINESS_KEY_ varchar(255),
    PARENT_ID_ varchar(64),
    CASE_DEF_ID_ varchar(64),
    ACT_ID_ varchar(255),
    PREV_STATE_ integer,
    CURRENT_STATE_ integer,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create case sentry part table --
​
create table ACT_RU_CASE_SENTRY_PART (
    ID_ varchar(64) NOT NULL,
    REV_ integer,
    CASE_INST_ID_ varchar(64),
    CASE_EXEC_ID_ varchar(64),
    SENTRY_ID_ varchar(255),
    TYPE_ varchar(255),
    SOURCE_CASE_EXEC_ID_ varchar(64),
    STANDARD_EVENT_ varchar(255),
    SATISFIED_ boolean,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create unique constraint on ACT_RE_CASE_DEF --
alter table ACT_RE_CASE_DEF
    add constraint ACT_UNIQ_CASE_DEF
    unique (KEY_,VERSION_);
​
-- create index on business key --
create index ACT_IDX_CASE_EXEC_BUSKEY on ACT_RU_CASE_EXECUTION(BUSINESS_KEY_);
​
-- create foreign key constraints on ACT_RU_CASE_EXECUTION --
alter table ACT_RU_CASE_EXECUTION
    add constraint ACT_FK_CASE_EXE_CASE_INST
    foreign key (CASE_INST_ID_)
    references ACT_RU_CASE_EXECUTION(ID_) on delete cascade on update cascade;
​
alter table ACT_RU_CASE_EXECUTION
    add constraint ACT_FK_CASE_EXE_PARENT
    foreign key (PARENT_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
alter table ACT_RU_CASE_EXECUTION
    add constraint ACT_FK_CASE_EXE_CASE_DEF
    foreign key (CASE_DEF_ID_)
    references ACT_RE_CASE_DEF(ID_);
​
-- create foreign key constraints on ACT_RU_VARIABLE --
alter table ACT_RU_VARIABLE
    add constraint ACT_FK_VAR_CASE_EXE
    foreign key (CASE_EXECUTION_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
alter table ACT_RU_VARIABLE
    add constraint ACT_FK_VAR_CASE_INST
    foreign key (CASE_INST_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
-- create foreign key constraints on ACT_RU_TASK --
alter table ACT_RU_TASK
    add constraint ACT_FK_TASK_CASE_EXE
    foreign key (CASE_EXECUTION_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
alter table ACT_RU_TASK
  add constraint ACT_FK_TASK_CASE_DEF
  foreign key (CASE_DEF_ID_)
  references ACT_RE_CASE_DEF(ID_);
​
-- create foreign key constraints on ACT_RU_CASE_SENTRY_PART --
alter table ACT_RU_CASE_SENTRY_PART
    add constraint ACT_FK_CASE_SENTRY_CASE_INST
    foreign key (CASE_INST_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
alter table ACT_RU_CASE_SENTRY_PART
    add constraint ACT_FK_CASE_SENTRY_CASE_EXEC
    foreign key (CASE_EXEC_ID_)
    references ACT_RU_CASE_EXECUTION(ID_);
​
-- create filter table
create table ACT_RU_FILTER (
  ID_ varchar(64) not null,
  REV_ integer not null,
  RESOURCE_TYPE_ varchar(255) not null,
  NAME_ varchar(255) not null,
  OWNER_ varchar(255),
  QUERY_ LONGTEXT not null,
  PROPERTIES_ LONGTEXT,
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- add index to improve job executor performance
create index ACT_IDX_JOB_PROCINST on ACT_RU_JOB(PROCESS_INSTANCE_ID_);
​
-- create historic case instance/activity table and indexes --
create table ACT_HI_CASEINST (
    ID_ varchar(64) not null,
    CASE_INST_ID_ varchar(64) not null,
    BUSINESS_KEY_ varchar(255),
    CASE_DEF_ID_ varchar(64) not null,
    CREATE_TIME_ datetime not null,
    CLOSE_TIME_ datetime,
    DURATION_ bigint,
    STATE_ integer,
    CREATE_USER_ID_ varchar(255),
    SUPER_CASE_INSTANCE_ID_ varchar(64),
    primary key (ID_),
    unique (CASE_INST_ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create table ACT_HI_CASEACTINST (
    ID_ varchar(64) not null,
    PARENT_ACT_INST_ID_ varchar(64),
    CASE_DEF_ID_ varchar(64) not null,
    CASE_INST_ID_ varchar(64) not null,
    CASE_ACT_ID_ varchar(255) not null,
    TASK_ID_ varchar(64),
    CALL_PROC_INST_ID_ varchar(64),
    CALL_CASE_INST_ID_ varchar(64),
    CASE_ACT_NAME_ varchar(255),
    CASE_ACT_TYPE_ varchar(255),
    CREATE_TIME_ datetime not null,
    END_TIME_ datetime,
    DURATION_ bigint,
    STATE_ integer,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create index ACT_IDX_HI_CAS_I_CLOSE on ACT_HI_CASEINST(CLOSE_TIME_);
create index ACT_IDX_HI_CAS_I_BUSKEY on ACT_HI_CASEINST(BUSINESS_KEY_);
create index ACT_IDX_HI_CAS_A_I_CREATE on ACT_HI_CASEACTINST(CREATE_TIME_);
create index ACT_IDX_HI_CAS_A_I_END on ACT_HI_CASEACTINST(END_TIME_);
create index ACT_IDX_HI_CAS_A_I_COMP on ACT_HI_CASEACTINST(CASE_ACT_ID_, END_TIME_, ID_);
create index ACT_IDX_HI_CAS_A_I_CASEINST on ACT_HI_CASEACTINST(CASE_INST_ID_, CASE_ACT_ID_);
​
create index ACT_IDX_TASK_ASSIGNEE on ACT_RU_TASK(ASSIGNEE_);
​
-- add case instance/execution to historic variable instance and detail --
alter table ACT_HI_VARINST
  add CASE_INST_ID_ varchar(64);
​
alter table ACT_HI_VARINST
  add CASE_EXECUTION_ID_ varchar(64);
​
alter table ACT_HI_DETAIL
  add CASE_INST_ID_ varchar(64);
​
alter table ACT_HI_DETAIL
  add CASE_EXECUTION_ID_ varchar(64);
​
create index ACT_IDX_HI_DETAIL_CASE_INST on ACT_HI_DETAIL(CASE_INST_ID_);
create index ACT_IDX_HI_DETAIL_CASE_EXEC on ACT_HI_DETAIL(CASE_EXECUTION_ID_);
create index ACT_IDX_HI_CASEVAR_CASE_INST on ACT_HI_VARINST(CASE_INST_ID_);
​
-- indexes to improve deployment
-- create index ACT_IDX_BYTEARRAY_NAME on ACT_GE_BYTEARRAY(NAME_);
-- create index ACT_IDX_DEPLOYMENT_NAME on ACT_RE_DEPLOYMENT(NAME_);
-- create index ACT_IDX_JOBDEF_PROC_DEF_ID ON ACT_RU_JOBDEF(PROC_DEF_ID_);
-- create index ACT_IDX_JOB_HANDLER_TYPE ON ACT_RU_JOB(HANDLER_TYPE_);
-- create index ACT_IDX_EVENT_SUBSCR_EVT_NAME ON ACT_RU_EVENT_SUBSCR(EVENT_NAME_);
-- create index ACT_IDX_PROCDEF_DEPLOYMENT_ID ON ACT_RE_PROCDEF(DEPLOYMENT_ID_);
​
-- case management --
​
ALTER TABLE ACT_RU_CASE_EXECUTION
  ADD SUPER_EXEC_ varchar(64);
​
ALTER TABLE ACT_RU_CASE_EXECUTION
  ADD REQUIRED_ boolean;
​
-- history --
​
ALTER TABLE ACT_HI_ACTINST
  ADD CALL_CASE_INST_ID_ varchar(64);
​
ALTER TABLE ACT_HI_PROCINST
  ADD SUPER_CASE_INSTANCE_ID_ varchar(64);
​
ALTER TABLE ACT_HI_CASEINST
  ADD SUPER_PROCESS_INSTANCE_ID_ varchar(64);
​
ALTER TABLE ACT_HI_CASEACTINST
  ADD REQUIRED_ boolean;
​
ALTER TABLE ACT_HI_OP_LOG
  ADD JOB_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD JOB_DEF_ID_ varchar(64);
​
create table ACT_HI_JOB_LOG (
    ID_ varchar(64) not null,
    TIMESTAMP_ timestamp not null,
    JOB_ID_ varchar(64) not null,
    JOB_DUEDATE_ timestamp NULL,
    JOB_RETRIES_ integer,
    JOB_EXCEPTION_MSG_ varchar(4000),
    JOB_EXCEPTION_STACK_ID_ varchar(64),
    JOB_STATE_ integer,
    JOB_DEF_ID_ varchar(64),
    JOB_DEF_TYPE_ varchar(255),
    JOB_DEF_CONFIGURATION_ varchar(255),
    ACT_ID_ varchar(64),
    EXECUTION_ID_ varchar(64),
    PROCESS_INSTANCE_ID_ varchar(64),
    PROCESS_DEF_ID_ varchar(64),
    PROCESS_DEF_KEY_ varchar(255),
    DEPLOYMENT_ID_ varchar(64),
    SEQUENCE_COUNTER_ bigint,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create index ACT_IDX_HI_JOB_LOG_PROCINST on ACT_HI_JOB_LOG(PROCESS_INSTANCE_ID_);
create index ACT_IDX_HI_JOB_LOG_PROCDEF on ACT_HI_JOB_LOG(PROCESS_DEF_ID_);
​
-- history: add columns PROC_DEF_KEY_, PROC_DEF_ID_, CASE_DEF_KEY_, CASE_DEF_ID_ --
​
ALTER TABLE ACT_HI_PROCINST
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_ACTINST
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_TASKINST
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_TASKINST
  ADD CASE_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_VARINST
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_VARINST
  ADD PROC_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_HI_VARINST
  ADD CASE_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_VARINST
  ADD CASE_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_HI_DETAIL
  ADD PROC_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_DETAIL
  ADD PROC_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_HI_DETAIL
  ADD CASE_DEF_KEY_ varchar(255);
​
ALTER TABLE ACT_HI_DETAIL
  ADD CASE_DEF_ID_ varchar(64);
​
ALTER TABLE ACT_HI_INCIDENT
  ADD PROC_DEF_KEY_ varchar(255);
​
-- sequence counter
​
ALTER TABLE ACT_RU_EXECUTION
  ADD SEQUENCE_COUNTER_ bigint;
​
ALTER TABLE ACT_HI_ACTINST
  ADD SEQUENCE_COUNTER_ bigint;
​
ALTER TABLE ACT_RU_VARIABLE
  ADD SEQUENCE_COUNTER_ bigint;
​
ALTER TABLE ACT_HI_DETAIL
  ADD SEQUENCE_COUNTER_ bigint;
​
ALTER TABLE ACT_RU_JOB
  ADD SEQUENCE_COUNTER_ bigint;
​
-- AUTHORIZATION --
​
-- add grant authorizations for group camunda-admin:
INSERT INTO
  ACT_RU_AUTHORIZATION (ID_, TYPE_, GROUP_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_, REV_)
VALUES
  ('camunda-admin-grant-process-definition', 1, 'camunda-admin', 6, '*', 2147483647, 1),
  ('camunda-admin-grant-task', 1, 'camunda-admin', 7, '*', 2147483647, 1),
  ('camunda-admin-grant-process-instance', 1, 'camunda-admin', 8, '*', 2147483647, 1),
  ('camunda-admin-grant-deployment', 1, 'camunda-admin', 9, '*', 2147483647, 1);
​
-- add global grant authorizations for new authorization resources:
-- DEPLOYMENT
-- PROCESS_DEFINITION
-- PROCESS_INSTANCE
-- TASK
-- with ALL permissions
​
INSERT INTO
  ACT_RU_AUTHORIZATION (ID_, TYPE_, USER_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_, REV_)
VALUES
  ('global-grant-process-definition', 0, '*', 6, '*', 2147483647, 1),
  ('global-grant-task', 0, '*', 7, '*', 2147483647, 1),
  ('global-grant-process-instance', 0, '*', 8, '*', 2147483647, 1),
  ('global-grant-deployment', 0, '*', 9, '*', 2147483647, 1);
​
-- variables --
​
ALTER TABLE ACT_RU_VARIABLE
  ADD IS_CONCURRENT_LOCAL_ TINYINT;
​
-- metrics --
​
create table ACT_RU_METER_LOG (
  ID_ varchar(64) not null,
  NAME_ varchar(64) not null,
  VALUE_ bigint,
  TIMESTAMP_ timestamp not null,
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create index ACT_IDX_METER_LOG on ACT_RU_METER_LOG(NAME_,TIMESTAMP_);
alter table ACT_HI_JOB_LOG
  modify ACT_ID_ varchar(255);
-- index for deadlock problem - https://app.camunda.com/jira/browse/CAM-4440 --
create index ACT_IDX_AUTH_RESOURCE_ID on ACT_RU_AUTHORIZATION(RESOURCE_ID_);
-- indexes to improve deployment
create index ACT_IDX_BYTEARRAY_NAME on ACT_GE_BYTEARRAY(NAME_);
create index ACT_IDX_DEPLOYMENT_NAME on ACT_RE_DEPLOYMENT(NAME_);
create index ACT_IDX_JOBDEF_PROC_DEF_ID ON ACT_RU_JOBDEF(PROC_DEF_ID_);
create index ACT_IDX_JOB_HANDLER_TYPE ON ACT_RU_JOB(HANDLER_TYPE_);
create index ACT_IDX_EVENT_SUBSCR_EVT_NAME ON ACT_RU_EVENT_SUBSCR(EVENT_NAME_);
create index ACT_IDX_PROCDEF_DEPLOYMENT_ID ON ACT_RE_PROCDEF(DEPLOYMENT_ID_);
-- INCREASE process def key column size https://app.camunda.com/jira/browse/CAM-4328 --
alter table ACT_RU_JOB
  modify PROCESS_DEF_KEY_ varchar(255);-- https://app.camunda.com/jira/browse/CAM-5364 --
create index ACT_IDX_AUTH_GROUP_ID on ACT_RU_AUTHORIZATION(GROUP_ID_);
-- metrics --
​
ALTER TABLE ACT_RU_METER_LOG
  ADD REPORTER_ varchar(255);
​
-- job prioritization --
​
ALTER TABLE ACT_RU_JOB
  ADD PRIORITY_ bigint NOT NULL
  DEFAULT 0;
​
ALTER TABLE ACT_RU_JOBDEF
  ADD JOB_PRIORITY_ bigint;
​
ALTER TABLE ACT_HI_JOB_LOG
  ADD JOB_PRIORITY_ bigint NOT NULL
  DEFAULT 0;
​
-- create decision definition table --
create table ACT_RE_DECISION_DEF (
    ID_ varchar(64) not null,
    REV_ integer,
    CATEGORY_ varchar(255),
    NAME_ varchar(255),
    KEY_ varchar(255) not null,
    VERSION_ integer not null,
    DEPLOYMENT_ID_ varchar(64),
    RESOURCE_NAME_ varchar(4000),
    DGRM_RESOURCE_NAME_ varchar(4000),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create unique constraint on ACT_RE_DECISION_DEF --
alter table ACT_RE_DECISION_DEF
    add constraint ACT_UNIQ_DECISION_DEF
    unique (KEY_,VERSION_);
​
-- case sentry part source --
​
ALTER TABLE ACT_RU_CASE_SENTRY_PART
  ADD SOURCE_ varchar(255);
​
-- create history decision instance table --
create table ACT_HI_DECINST (
    ID_ varchar(64) NOT NULL,
    DEC_DEF_ID_ varchar(64) NOT NULL,
    DEC_DEF_KEY_ varchar(255) NOT NULL,
    DEC_DEF_NAME_ varchar(255),
    PROC_DEF_KEY_ varchar(255),
    PROC_DEF_ID_ varchar(64),
    PROC_INST_ID_ varchar(64),
    CASE_DEF_KEY_ varchar(255),
    CASE_DEF_ID_ varchar(64),
    CASE_INST_ID_ varchar(64),
    ACT_INST_ID_ varchar(64),
    ACT_ID_ varchar(255),
    EVAL_TIME_ datetime not null,
    COLLECT_VALUE_ double,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create history decision input table --
create table ACT_HI_DEC_IN (
    ID_ varchar(64) NOT NULL,
    DEC_INST_ID_ varchar(64) NOT NULL,
    CLAUSE_ID_ varchar(64) NOT NULL,
    CLAUSE_NAME_ varchar(255),
    VAR_TYPE_ varchar(100),
    BYTEARRAY_ID_ varchar(64),
    DOUBLE_ double,
    LONG_ bigint,
    TEXT_ varchar(4000),
    TEXT2_ varchar(4000),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create history decision output table --
create table ACT_HI_DEC_OUT (
    ID_ varchar(64) NOT NULL,
    DEC_INST_ID_ varchar(64) NOT NULL,
    CLAUSE_ID_ varchar(64) NOT NULL,
    CLAUSE_NAME_ varchar(255),
    RULE_ID_ varchar(64) NOT NULL,
    RULE_ORDER_ integer,
    VAR_NAME_ varchar(255),
    VAR_TYPE_ varchar(100),
    BYTEARRAY_ID_ varchar(64),
    DOUBLE_ double,
    LONG_ bigint,
    TEXT_ varchar(4000),
    TEXT2_ varchar(4000),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create indexes for historic decision tables
create index ACT_IDX_HI_DEC_INST_ID on ACT_HI_DECINST(DEC_DEF_ID_);
create index ACT_IDX_HI_DEC_INST_KEY on ACT_HI_DECINST(DEC_DEF_KEY_);
create index ACT_IDX_HI_DEC_INST_PI on ACT_HI_DECINST(PROC_INST_ID_);
create index ACT_IDX_HI_DEC_INST_CI on ACT_HI_DECINST(CASE_INST_ID_);
create index ACT_IDX_HI_DEC_INST_ACT on ACT_HI_DECINST(ACT_ID_);
create index ACT_IDX_HI_DEC_INST_ACT_INST on ACT_HI_DECINST(ACT_INST_ID_);
create index ACT_IDX_HI_DEC_INST_TIME on ACT_HI_DECINST(EVAL_TIME_);
​
create index ACT_IDX_HI_DEC_IN_INST on ACT_HI_DEC_IN(DEC_INST_ID_);
create index ACT_IDX_HI_DEC_IN_CLAUSE on ACT_HI_DEC_IN(DEC_INST_ID_, CLAUSE_ID_);
​
create index ACT_IDX_HI_DEC_OUT_INST on ACT_HI_DEC_OUT(DEC_INST_ID_);
create index ACT_IDX_HI_DEC_OUT_RULE on ACT_HI_DEC_OUT(RULE_ORDER_, CLAUSE_ID_);
​
-- add grant authorization for group camunda-admin:
INSERT INTO
  ACT_RU_AUTHORIZATION (ID_, TYPE_, GROUP_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_, REV_)
VALUES
  ('camunda-admin-grant-decision-definition', 1, 'camunda-admin', 10, '*', 2147483647, 1);
​
-- external tasks --
​
create table ACT_RU_EXT_TASK (
  ID_ varchar(64) not null,
  REV_ integer not null,
  WORKER_ID_ varchar(255),
  TOPIC_NAME_ varchar(255),
  RETRIES_ integer,
  ERROR_MSG_ varchar(4000),
  LOCK_EXP_TIME_ timestamp NULL,
  SUSPENSION_STATE_ integer,
  EXECUTION_ID_ varchar(64),
  PROC_INST_ID_ varchar(64),
  PROC_DEF_ID_ varchar(64),
  PROC_DEF_KEY_ varchar(255),
  ACT_ID_ varchar(255),
  ACT_INST_ID_ varchar(64),
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
alter table ACT_RU_EXT_TASK
    add constraint ACT_FK_EXT_TASK_EXE
    foreign key (EXECUTION_ID_)
    references ACT_RU_EXECUTION (ID_);
​
create index ACT_IDX_EXT_TASK_TOPIC on ACT_RU_EXT_TASK(TOPIC_NAME_);
​
-- deployment --
​
ALTER TABLE ACT_RE_DEPLOYMENT
  ADD SOURCE_ varchar(255);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD DEPLOYMENT_ID_ varchar(64);
​
-- job suspension state
​
ALTER TABLE ACT_RU_JOB
  MODIFY COLUMN SUSPENSION_STATE_ integer
  DEFAULT 1;
​
  -- relevant for jobs created in Camunda 7.0
UPDATE ACT_RU_JOB
  SET SUSPENSION_STATE_ = 1
  WHERE SUSPENSION_STATE_ IS NULL;
​
ALTER TABLE ACT_RU_JOB
  MODIFY COLUMN SUSPENSION_STATE_ integer
  NOT NULL DEFAULT 1;
-- index to improve historic activity instance query - https://app.camunda.com/jira/browse/CAM-5257 --
create index ACT_IDX_HI_ACT_INST_STATS on ACT_HI_ACTINST(PROC_DEF_ID_, ACT_ID_, END_TIME_, ACT_INST_STATE_);
-- index to prevent deadlock on fk constraint - https://app.camunda.com/jira/browse/CAM-5440 --
create index ACT_IDX_EXT_TASK_EXEC on ACT_RU_EXT_TASK(EXECUTION_ID_);
-- https://app.camunda.com/jira/browse/CAM-5364 --
-- create index ACT_IDX_AUTH_GROUP_ID on ACT_RU_AUTHORIZATION(GROUP_ID_);
-- INCREASE process def key column size https://app.camunda.com/jira/browse/CAM-4328 --
alter table ACT_RU_JOB
  modify PROCESS_DEF_KEY_ varchar(255);-- semantic version --
​
ALTER TABLE ACT_RE_PROCDEF
  ADD VERSION_TAG_ varchar(64);
​
create index ACT_IDX_PROCDEF_VER_TAG on ACT_RE_PROCDEF(VERSION_TAG_);
​
-- AUTHORIZATION --
​
-- add grant authorizations for group camunda-admin:
INSERT INTO
  ACT_RU_AUTHORIZATION (ID_, TYPE_, GROUP_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_, REV_)
VALUES
  ('camunda-admin-grant-tenant', 1, 'camunda-admin', 11, '*', 2147483647, 1),
  ('camunda-admin-grant-tenant-membership', 1, 'camunda-admin', 12, '*', 2147483647, 1),
  ('camunda-admin-grant-batch', 1, 'camunda-admin', 13, '*', 2147483647, 1);
​
-- tenant id --
​
-- ALTER TABLE ACT_RE_DEPLOYMENT
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_DEPLOYMENT_TENANT_ID on ACT_RE_DEPLOYMENT(TENANT_ID_);
​
-- ALTER TABLE ACT_RE_PROCDEF
--  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_RE_PROCDEF
   DROP INDEX ACT_UNIQ_PROCDEF;
​
create index ACT_IDX_PROCDEF_TENANT_ID ON ACT_RE_PROCDEF(TENANT_ID_);
​
-- ALTER TABLE ACT_RU_EXECUTION
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_EXEC_TENANT_ID on ACT_RU_EXECUTION(TENANT_ID_);
​
-- ALTER TABLE ACT_RU_TASK
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_TASK_TENANT_ID on ACT_RU_TASK(TENANT_ID_);
​
ALTER TABLE ACT_RU_VARIABLE
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_VARIABLE_TENANT_ID on ACT_RU_VARIABLE(TENANT_ID_);
​
-- ALTER TABLE ACT_RU_EVENT_SUBSCR
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_EVENT_SUBSCR_TENANT_ID on ACT_RU_EVENT_SUBSCR(TENANT_ID_);
​
-- ALTER TABLE ACT_RU_JOB
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_JOB_TENANT_ID on ACT_RU_JOB(TENANT_ID_);
​
ALTER TABLE ACT_RU_JOBDEF
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_JOBDEF_TENANT_ID on ACT_RU_JOBDEF(TENANT_ID_);
​
ALTER TABLE ACT_RU_INCIDENT
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_RU_IDENTITYLINK
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_INC_TENANT_ID on ACT_RU_INCIDENT(TENANT_ID_);
​
ALTER TABLE ACT_RU_EXT_TASK
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_EXT_TASK_TENANT_ID on ACT_RU_EXT_TASK(TENANT_ID_);
​
ALTER TABLE ACT_RE_DECISION_DEF
       DROP INDEX ACT_UNIQ_DECISION_DEF;
​
ALTER TABLE ACT_RE_DECISION_DEF
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_DEC_DEF_TENANT_ID on ACT_RE_DECISION_DEF(TENANT_ID_);
​
ALTER TABLE ACT_RE_CASE_DEF
       DROP INDEX ACT_UNIQ_CASE_DEF;
​
ALTER TABLE ACT_RE_CASE_DEF
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_CASE_DEF_TENANT_ID on ACT_RE_CASE_DEF(TENANT_ID_);
​
ALTER TABLE ACT_GE_BYTEARRAY
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_RU_CASE_EXECUTION
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_CASE_EXEC_TENANT_ID on ACT_RU_CASE_EXECUTION(TENANT_ID_);
​
ALTER TABLE ACT_RU_CASE_SENTRY_PART
  ADD TENANT_ID_ varchar(64);
​
-- user on historic decision instance --
​
ALTER TABLE ACT_HI_DECINST
  ADD USER_ID_ varchar(255);
​
  -- tenant id on history --
​
-- ALTER TABLE ACT_HI_PROCINST
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_PRO_INST_TENANT_ID on ACT_HI_PROCINST(TENANT_ID_);
​
-- ALTER TABLE ACT_HI_ACTINST
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_ACT_INST_TENANT_ID on ACT_HI_ACTINST(TENANT_ID_);
​
-- ALTER TABLE ACT_HI_TASKINST
--  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_TASK_INST_TENANT_ID on ACT_HI_TASKINST(TENANT_ID_);
​
ALTER TABLE ACT_HI_VARINST
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_VAR_INST_TENANT_ID on ACT_HI_VARINST(TENANT_ID_);
​
ALTER TABLE ACT_HI_DETAIL
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_DETAIL_TENANT_ID on ACT_HI_DETAIL(TENANT_ID_);
​
ALTER TABLE ACT_HI_INCIDENT
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_INCIDENT_TENANT_ID on ACT_HI_INCIDENT(TENANT_ID_);
​
ALTER TABLE ACT_HI_JOB_LOG
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_JOB_LOG_TENANT_ID on ACT_HI_JOB_LOG(TENANT_ID_);
​
ALTER TABLE ACT_HI_COMMENT
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_HI_ATTACHMENT
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_HI_OP_LOG
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_HI_DEC_IN
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_HI_DEC_OUT
  ADD TENANT_ID_ varchar(64);
​
ALTER TABLE ACT_HI_DECINST
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_DEC_INST_TENANT_ID on ACT_HI_DECINST(TENANT_ID_);
​
ALTER TABLE ACT_HI_CASEINST
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_CAS_I_TENANT_ID on ACT_HI_CASEINST(TENANT_ID_);
​
ALTER TABLE ACT_HI_CASEACTINST
  ADD TENANT_ID_ varchar(64);
​
create index ACT_IDX_HI_CAS_A_I_TENANT_ID on ACT_HI_CASEACTINST(TENANT_ID_);
​
-- add tenant table
​
create table ACT_ID_TENANT (
    ID_ varchar(64),
    REV_ integer,
    NAME_ varchar(255),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create table ACT_ID_TENANT_MEMBER (
    ID_ varchar(64) not null,
    TENANT_ID_ varchar(64) not null,
    USER_ID_ varchar(64),
    GROUP_ID_ varchar(64),
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
alter table ACT_ID_TENANT_MEMBER
    add constraint ACT_UNIQ_TENANT_MEMB_USER
    unique (TENANT_ID_, USER_ID_);
​
alter table ACT_ID_TENANT_MEMBER
    add constraint ACT_UNIQ_TENANT_MEMB_GROUP
    unique (TENANT_ID_, GROUP_ID_);
​
alter table ACT_ID_TENANT_MEMBER
    add constraint ACT_FK_TENANT_MEMB
    foreign key (TENANT_ID_)
    references ACT_ID_TENANT (ID_);
​
alter table ACT_ID_TENANT_MEMBER
    add constraint ACT_FK_TENANT_MEMB_USER
    foreign key (USER_ID_)
    references ACT_ID_USER (ID_);
​
alter table ACT_ID_TENANT_MEMBER
    add constraint ACT_FK_TENANT_MEMB_GROUP
    foreign key (GROUP_ID_)
    references ACT_ID_GROUP (ID_);
​
--  BATCH --
​
-- remove not null from job definition table --
alter table ACT_RU_JOBDEF
  modify PROC_DEF_ID_ varchar(64),
  modify PROC_DEF_KEY_ varchar(255),
  modify ACT_ID_ varchar(255);
​
create table ACT_RU_BATCH (
  ID_ varchar(64) not null,
  REV_ integer not null,
  TYPE_ varchar(255),
  TOTAL_JOBS_ integer,
  JOBS_CREATED_ integer,
  JOBS_PER_SEED_ integer,
  INVOCATIONS_PER_JOB_ integer,
  SEED_JOB_DEF_ID_ varchar(64),
  BATCH_JOB_DEF_ID_ varchar(64),
  MONITOR_JOB_DEF_ID_ varchar(64),
  SUSPENSION_STATE_ integer,
  CONFIGURATION_ varchar(255),
  TENANT_ID_ varchar(64),
  primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
create table ACT_HI_BATCH (
    ID_ varchar(64) not null,
    TYPE_ varchar(255),
    TOTAL_JOBS_ integer,
    JOBS_PER_SEED_ integer,
    INVOCATIONS_PER_JOB_ integer,
    SEED_JOB_DEF_ID_ varchar(64),
    MONITOR_JOB_DEF_ID_ varchar(64),
    BATCH_JOB_DEF_ID_ varchar(64),
    TENANT_ID_  varchar(64),
    START_TIME_ datetime not null,
    END_TIME_ datetime,
    primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
​
-- create table ACT_HI_IDENTITYLINK (
--    ID_ varchar(64) not null,
--    TIMESTAMP_ timestamp not null,
--    TYPE_ varchar(255),
--    USER_ID_ varchar(255),
--    GROUP_ID_ varchar(255),
--    TASK_ID_ varchar(64),
--    PROC_DEF_ID_ varchar(64),
--    OPERATION_TYPE_ varchar(64),
--    ASSIGNER_ID_ varchar(64),
--    PROC_DEF_KEY_ varchar(255),
--    TENANT_ID_ varchar(64),
--    primary key (ID_)
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
--
-- create index ACT_IDX_HI_IDENT_LNK_USER on ACT_HI_IDENTITYLINK(USER_ID_);
create index ACT_IDX_HI_IDENT_LNK_GROUP on ACT_HI_IDENTITYLINK(GROUP_ID_);
-- create index ACT_IDX_HI_IDENT_LNK_TENANT_ID on ACT_HI_IDENTITYLINK(TENANT_ID_);
​
create index ACT_IDX_JOB_JOB_DEF_ID on ACT_RU_JOB(JOB_DEF_ID_);
create index ACT_IDX_HI_JOB_LOG_JOB_DEF_ID on ACT_HI_JOB_LOG(JOB_DEF_ID_);
​
create index ACT_IDX_BATCH_SEED_JOB_DEF ON ACT_RU_BATCH(SEED_JOB_DEF_ID_);
alter table ACT_RU_BATCH
    add constraint ACT_FK_BATCH_SEED_JOB_DEF
    foreign key (SEED_JOB_DEF_ID_)
    references ACT_RU_JOBDEF (ID_);
​
create index ACT_IDX_BATCH_MONITOR_JOB_DEF ON ACT_RU_BATCH(MONITOR_JOB_DEF_ID_);
alter table ACT_RU_BATCH
    add constraint ACT_FK_BATCH_MONITOR_JOB_DEF
    foreign key (MONITOR_JOB_DEF_ID_)
    references ACT_RU_JOBDEF (ID_);
​
create index ACT_IDX_BATCH_JOB_DEF ON ACT_RU_BATCH(BATCH_JOB_DEF_ID_);
alter table ACT_RU_BATCH
    add constraint ACT_FK_BATCH_JOB_DEF
    foreign key (BATCH_JOB_DEF_ID_)
    references ACT_RU_JOBDEF (ID_);
​
-- TASK PRIORITY --
​
ALTER TABLE ACT_RU_EXT_TASK
  ADD PRIORITY_ bigint NOT NULL DEFAULT 0;
​
create index ACT_IDX_EXT_TASK_PRIORITY ON ACT_RU_EXT_TASK(PRIORITY_);
​
​
-- HI OP PROC INDECIES --
​
create index ACT_IDX_HI_OP_LOG_PROCINST on ACT_HI_OP_LOG(PROC_INST_ID_);
create index ACT_IDX_HI_OP_LOG_PROCDEF on ACT_HI_OP_LOG(PROC_DEF_ID_);
​
-- JOB_DEF_ID_ on INCIDENTS --
ALTER TABLE ACT_RU_INCIDENT
  ADD JOB_DEF_ID_ varchar(64);
​
create index ACT_IDX_INC_JOB_DEF on ACT_RU_INCIDENT(JOB_DEF_ID_);
alter table ACT_RU_INCIDENT
    add constraint ACT_FK_INC_JOB_DEF
    foreign key (JOB_DEF_ID_)
    references ACT_RU_JOBDEF (ID_);
​
ALTER TABLE ACT_HI_INCIDENT
  ADD JOB_DEF_ID_ varchar(64);
​
-- BATCH_ID_ on ACT_HI_OP_LOG --
ALTER TABLE ACT_HI_OP_LOG
  ADD BATCH_ID_ varchar(64);
​
-- alter table ACT_HI_IDENTITYLINK to match Camundas version, note that some data may not be filled for old instances! 
alter table ACT_HI_IDENTITYLINK add column (
    ASSIGNER_ID_ varchar(64),
    OPERATION_TYPE_ varchar(64),
    PROC_DEF_ID_ varchar(64),
    PROC_DEF_KEY_ varchar(255),
    TENANT_ID_ varchar(64),
    TIMESTAMP_ timestamp);
--    drop PROC_INST_ID_, -- done in drop script
​
create index ACT_IDX_HI_IDENT_LNK_TENANT_ID on ACT_HI_IDENTITYLINK(TENANT_ID_);
​
-- changes in attributes
alter table ACT_HI_ACTINST      MODIFY COLUMN ASSIGNEE_ varchar(64);
​
alter table ACT_HI_ACTINST      MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_HI_PROCINST     MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_HI_TASKINST     MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RE_DEPLOYMENT   MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RE_PROCDEF      MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RU_EVENT_SUBSCR MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RU_EXECUTION    MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RU_JOB          MODIFY COLUMN TENANT_ID_ varchar(64);
alter table ACT_RU_TASK         MODIFY COLUMN TENANT_ID_ varchar(64);
​
-- delete users and groups, as you have to re-create them (hashed passwords, different group types, required authorizations)
delete from ACT_ID_MEMBERSHIP;
delete from ACT_ID_TENANT_MEMBER;
delete from ACT_ID_INFO;
delete from ACT_ID_USER;
delete from ACT_ID_GROUP;
​
-- drop tables not used in Camunda
drop table if exists  ACT_EVT_LOG cascade; 
drop table if exists  ACT_PROCDEF_INFO cascade;
drop table if exists  ACT_RE_MODEL cascade;
​
-- columns not used in camunda                                                               
alter table ACT_HI_IDENTITYLINK DROP COLUMN PROC_INST_ID_;
​
alter table ACT_HI_TASKINST     DROP COLUMN CATEGORY_;
alter table ACT_RE_DEPLOYMENT   DROP COLUMN CATEGORY_;
alter table ACT_RU_TASK         DROP COLUMN CATEGORY_;
alter table ACT_HI_TASKINST     DROP COLUMN CLAIM_TIME_;
alter table ACT_HI_VARINST      DROP COLUMN CREATE_TIME_;
alter table ACT_RE_PROCDEF      DROP COLUMN DESCRIPTION_;
alter table ACT_HI_VARINST      DROP COLUMN LAST_UPDATED_TIME_;
alter table ACT_RU_EXECUTION    DROP COLUMN LOCK_TIME_;
alter table ACT_HI_PROCINST     DROP COLUMN NAME_;
alter table ACT_RU_EXECUTION    DROP COLUMN NAME_;
ALTER TABLE ACT_RU_IDENTITYLINK DROP FOREIGN KEY ACT_FK_IDL_PROCINST;
alter table ACT_RU_IDENTITYLINK DROP COLUMN PROC_INST_ID_;
alter table ACT_RU_EVENT_SUBSCR DROP COLUMN PROC_DEF_ID_;
alter table ACT_RU_JOB          DROP FOREIGN KEY ACT_FK_JOB_PROC_DEF;
alter table ACT_RU_JOB          DROP COLUMN PROC_DEF_ID_;
alter table ACT_HI_ATTACHMENT   DROP COLUMN TIME_;
alter table ACT_HI_TASKINST     DROP COLUMN FORM_KEY_;
alter table ACT_RU_TASK         DROP COLUMN FORM_KEY_;
alter table ACT_RE_PROCDEF      DROP COLUMN HAS_GRAPHICAL_NOTATION_;
​
-- drop indexes not used in Camunda
ALTER TABLE act_hi_actinst drop index ACT_IDX_HI_ACT_INST_EXEC;
ALTER TABLE act_hi_identitylink drop index ACT_IDX_HI_IDENT_LNK_TASK;
ALTER TABLE act_hi_varinst drop index ACT_IDX_HI_PROCVAR_TASK_ID;
ALTER TABLE act_hi_taskinst drop index ACT_IDX_HI_TASK_INST_PROCINST;
​
ALTER TABLE act_hi_actinst
DROP COLUMN DELETE_REASON_,
ADD INDEX ACT_IDX_HI_ACT_INST_COMP (ID_, EXECUTION_ID_, ACT_ID_, END_TIME_) ,
ADD INDEX ACT_IDX_HI_ACT_INST_PROC_DEF_KEY (PROC_DEF_KEY_) ;
​
ALTER TABLE act_hi_attachment
ADD INDEX ACT_IDX_HI_ATTACHMENT_CONTENT (CONTENT_ID_) ,
ADD INDEX ACT_IDX_HI_ATTACHMENT_PROCINST (PROC_INST_ID_) ,
ADD INDEX ACT_IDX_HI_ATTACHMENT_TASK (TASK_ID_) ;
​
ALTER TABLE act_hi_comment
ADD INDEX ACT_IDX_HI_COMMENT_TASK (TASK_ID_) ,
ADD INDEX ACT_IDX_HI_COMMENT_PROCINST (PROC_INST_ID_) ;
​
ALTER TABLE act_hi_decinst
ADD COLUMN ROOT_DEC_INST_ID_  varchar(64) NULL AFTER USER_ID_,
ADD COLUMN DEC_REQ_ID_  varchar(64) NULL AFTER ROOT_DEC_INST_ID_,
ADD COLUMN DEC_REQ_KEY_  varchar(255) NULL AFTER DEC_REQ_ID_,
ADD INDEX ACT_IDX_HI_DEC_INST_ROOT_ID (ROOT_DEC_INST_ID_) ,
ADD INDEX ACT_IDX_HI_DEC_INST_REQ_ID (DEC_REQ_ID_) ,
ADD INDEX ACT_IDX_HI_DEC_INST_REQ_KEY (DEC_REQ_KEY_) ;
​
ALTER TABLE act_hi_detail
ADD COLUMN OPERATION_ID_  varchar(64) NULL AFTER TENANT_ID_,
ADD INDEX ACT_IDX_HI_DETAIL_PROC_DEF_KEY (PROC_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_DETAIL_BYTEAR (BYTEARRAY_ID_) ;
​
CREATE TABLE act_hi_ext_task_log (
  ID_ varchar(64) COLLATE utf8_bin NOT NULL,
  TIMESTAMP_ timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  EXT_TASK_ID_ varchar(64) COLLATE utf8_bin NOT NULL,
  RETRIES_ int(11) DEFAULT NULL,
  TOPIC_NAME_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  WORKER_ID_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  PRIORITY_ bigint(20) NOT NULL DEFAULT '0',
  ERROR_MSG_ varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  ERROR_DETAILS_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  ACT_ID_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  ACT_INST_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  EXECUTION_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  PROC_INST_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  PROC_DEF_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  PROC_DEF_KEY_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  TENANT_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  STATE_ int(11) DEFAULT NULL,
  REV_ int(11) DEFAULT NULL,
  PRIMARY KEY (ID_),
  KEY ACT_HI_EXT_TASK_LOG_PROCINST (PROC_INST_ID_),
  KEY ACT_HI_EXT_TASK_LOG_PROCDEF (PROC_DEF_ID_),
  KEY ACT_HI_EXT_TASK_LOG_PROC_DEF_KEY (PROC_DEF_KEY_),
  KEY ACT_HI_EXT_TASK_LOG_TENANT_ID (TENANT_ID_),
  KEY ACT_IDX_HI_EXTTASKLOG_ERRORDET (ERROR_DETAILS_ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
​
ALTER TABLE act_hi_identitylink
ADD INDEX ACT_IDX_HI_IDENT_LNK_PROC_DEF_KEY (PROC_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_IDENT_LINK_TASK (TASK_ID_) ;
​
ALTER TABLE act_hi_incident
ADD INDEX ACT_IDX_HI_INCIDENT_PROC_DEF_KEY (PROC_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_INCIDENT_PROCINST (PROC_INST_ID_) ;
​
ALTER TABLE act_hi_job_log
ADD INDEX ACT_IDX_HI_JOB_LOG_PROC_DEF_KEY (PROCESS_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_JOB_LOG_EX_STACK (JOB_EXCEPTION_STACK_ID_) ;
​
ALTER TABLE act_hi_procinst
ADD COLUMN STATE_  varchar(255) NULL AFTER PROC_DEF_KEY_,
ADD INDEX ACT_IDX_HI_PRO_INST_PROC_DEF_KEY (PROC_DEF_KEY_) ;
​
ALTER TABLE act_hi_taskinst
ADD INDEX ACT_IDX_HI_TASK_INST_PROC_DEF_KEY (PROC_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_TASKINST_PROCINST (PROC_INST_ID_) ,
ADD INDEX ACT_IDX_HI_TASKINSTID_PROCINST (ID_, PROC_INST_ID_) ;
​
ALTER TABLE act_hi_varinst
ADD COLUMN STATE_  varchar(20) NULL AFTER TENANT_ID_,
ADD INDEX ACT_IDX_HI_VAR_INST_PROC_DEF_KEY (PROC_DEF_KEY_) ,
ADD INDEX ACT_IDX_HI_VARINST_BYTEAR (BYTEARRAY_ID_) ;
​
ALTER TABLE act_re_case_def
ADD COLUMN HISTORY_TTL_  int(11) NULL AFTER TENANT_ID_;
​
CREATE TABLE act_re_decision_req_def (
  ID_ varchar(64) COLLATE utf8_bin NOT NULL,
  REV_ int(11) DEFAULT NULL,
  CATEGORY_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  NAME_ varchar(255) COLLATE utf8_bin DEFAULT NULL,
  KEY_ varchar(255) COLLATE utf8_bin NOT NULL,
  VERSION_ int(11) NOT NULL,
  DEPLOYMENT_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  RESOURCE_NAME_ varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  DGRM_RESOURCE_NAME_ varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  TENANT_ID_ varchar(64) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (ID_),
  KEY ACT_IDX_DEC_REQ_DEF_TENANT_ID (TENANT_ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
​
ALTER TABLE act_re_decision_def
ADD COLUMN DEC_REQ_ID_  varchar(64) NULL AFTER DGRM_RESOURCE_NAME_,
ADD COLUMN DEC_REQ_KEY_  varchar(255) NULL AFTER DEC_REQ_ID_,
ADD COLUMN HISTORY_TTL_  int(11) NULL AFTER TENANT_ID_,
ADD COLUMN VERSION_TAG_  varchar(64) NULL AFTER HISTORY_TTL_,
ADD INDEX ACT_IDX_DEC_DEF_REQ_ID (DEC_REQ_ID_) ;
​
ALTER TABLE act_re_decision_def ADD CONSTRAINT ACT_FK_DEC_REQ FOREIGN KEY (DEC_REQ_ID_) REFERENCES act_re_decision_req_def (ID_);
​
ALTER TABLE act_re_deployment
DROP COLUMN KEY_,
DROP COLUMN ENGINE_VERSION_,
MODIFY COLUMN DEPLOY_TIME_  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER TENANT_ID_;
​
ALTER TABLE act_re_procdef
DROP COLUMN ENGINE_VERSION_,
ADD COLUMN HISTORY_TTL_  int(11) NULL AFTER VERSION_TAG_;
​
ALTER TABLE act_ru_case_sentry_part
ADD COLUMN VARIABLE_EVENT_  varchar(255) NULL AFTER SOURCE_,
ADD COLUMN VARIABLE_NAME_  varchar(255) NULL AFTER VARIABLE_EVENT_;
​
DROP TABLE IF EXISTS act_ru_deadletter_job;
​
ALTER TABLE act_ru_execution
DROP COLUMN ROOT_PROC_INST_ID_,
DROP COLUMN IS_MI_ROOT_,
DROP COLUMN START_TIME_,
DROP COLUMN START_USER_ID_,
DROP COLUMN IS_COUNT_ENABLED_,
DROP COLUMN EVT_SUBSCR_COUNT_,
DROP COLUMN TASK_COUNT_,
DROP COLUMN JOB_COUNT_,
DROP COLUMN TIMER_JOB_COUNT_,
DROP COLUMN SUSP_JOB_COUNT_,
DROP COLUMN DEADLETTER_JOB_COUNT_,
DROP COLUMN VAR_COUNT_,
DROP COLUMN ID_LINK_COUNT_,
DROP INDEX ACT_IDC_EXEC_ROOT;
​
ALTER TABLE act_ru_ext_task
ADD COLUMN ERROR_DETAILS_ID_  varchar(64) NULL AFTER ERROR_MSG_,
ADD INDEX ACT_IDX_EXT_TASK_ERR_DETAILS (ERROR_DETAILS_ID_) ;
​
ALTER TABLE act_ru_ext_task ADD CONSTRAINT ACT_FK_EXT_TASK_ERROR_DETAILS FOREIGN KEY (ERROR_DETAILS_ID_) REFERENCES act_ge_bytearray (ID_);
​
ALTER TABLE act_ru_job DROP FOREIGN KEY ACT_FK_JOB_EXECUTION;
​
ALTER TABLE act_ru_job DROP FOREIGN KEY ACT_FK_JOB_PROCESS_INSTANCE;
​
ALTER TABLE act_ru_meter_log
ADD COLUMN MILLISECONDS_  bigint(20) NULL DEFAULT 0 AFTER REPORTER_,
ADD INDEX ACT_IDX_METER_LOG_MS (MILLISECONDS_) ,
ADD INDEX ACT_IDX_METER_LOG_NAME_MS (NAME_, MILLISECONDS_) ,
ADD INDEX ACT_IDX_METER_LOG_REPORT (NAME_, REPORTER_, MILLISECONDS_) ,
ADD INDEX ACT_IDX_METER_LOG_TIME (TIMESTAMP_) ;
​
DROP TABLE IF EXISTS act_ru_suspended_job;
​
ALTER TABLE act_ru_task
DROP COLUMN CLAIM_TIME_,
MODIFY COLUMN CREATE_TIME_  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER PRIORITY_;
​
DROP TABLE IF EXISTS act_ru_timer_job;

 

代码迁移

上面说过,如果单纯的新项目,根本不需要写什么代码,引几个maven库就能跑起来了,只是我原来的rest接口不可能都替换成官方的rest接口,那样工作量太大了,成本太高了,只好根据IDE的错误提醒一项一项地解决,过程就不说了,贴出修改后的Service类

package cn.jia.workflow.service;
​
import cn.jia.workflow.entity.DeploymentExample;
import cn.jia.workflow.entity.ProcessDefinitionExample;
import cn.jia.workflow.entity.ProcessInstanceExample;
import cn.jia.workflow.entity.TaskExample;
import com.github.pagehelper.Page;
import org.camunda.bpm.engine.history.HistoricProcessInstance;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.history.HistoricVariableInstance;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.Task;
​
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
​
public interface WorkflowService {
​
  /**
   * 部署工作流
   * @param deployment
   * @param inputStream
   */
  void deployProcess(Deployment deployment, InputStream inputStream);
  
  void deployProcess(Deployment deployment, ZipInputStream zipInputStream);
  
  /**
   * 获取工作流列表
   * @return
   */
  List getDeployment();
  
  /**
   * 分页获取工作流列表
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getDeployment(DeploymentExample example, int pageNo, int pageSize);
  
  /**
   * 根据ID获取工作流
   * @param deploymentId
   * @return
   */
  Deployment getDeploymentById(String deploymentId);
  
  /**
   * 获取工作流部署资源列表
   * @param deploymentId
   * @return
   */
  List getDeploymentResourceNames(String deploymentId);
  
  /**
   * 删除工作流
   * @param deploymentId
   */
  void deleteDeployment(String deploymentId);
  
  /**
   * 获取工作流定义列表
   * @param example
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getProcessDefinition(ProcessDefinitionExample example, int pageNo, int pageSize);
  
  /**
   * 获取工作流定义信息
   * @param processDefinitionId
   * @return
   */
  ProcessDefinition getProcessDefinitionById(String processDefinitionId);
  
  /**
   * 获取工作流图解内容
   * @param processDefinitionId
   * @return
   */
  InputStream getProcessDiagram(String processDefinitionId);
  
  /**
   * 获取工作流定义内容
   * @param deploymentId
   * @param resourceName
   * @return
   */
  InputStream getResourceAsStream(String deploymentId, String resourceName);
  
  /**
   * 激活工作流
   * @param processDefinitionId
   */
  void activateProcessDefinition(String processDefinitionId);
  
  /**
   * 挂起工作流
   * @param processDefinitionId
   */
  void suspendProcessDefinition(String processDefinitionId);
​
  /**
   * 开始任务
   * @param processDefinitionKey
   * @param businessKey
   * @param variables
   */
  void startProcess(String processDefinitionKey, String businessKey, Map variables);
​
  /**
   * 获得某个人的任务别表
   * @param assignee
   * @return
   */
  List getTasks(String assignee);
  
  /**
   * 分页显示某个人的任务列表
   * @param example
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getTasks(TaskExample example, int pageNo, int pageSize);
  
  /**
   * 根据业务编号查找当前用户的最新任务
   * @param businessKey
   * @return
   */
  Task getTaskByBusinessKey(String businessKey, String assignee);
  
  /**
   * 根据业务编号查找最新任务列表
   * @param businessKey
   * @return
   */
  List getTaskByBusinessKey(String businessKey);
  
  /**
   * 根据任务ID获取任务信息
   * @param taskId
   * @return
   */
  Task getTaskById(String taskId);
  
  /**
   * 根据实例ID获取
   * @param processInstanceId
   * @return
   */
  List getTaskByProcessInstanceId(String processInstanceId);
​
  /**
   * 完成任务
   * @param taskId
   * @param variables
   */
  void completeTasks(String taskId, Map variables);
  
  /**
   * 删除流程实例
   * @param processInstanceId
   * @param deleteReason
   */
  void deleteProcessInstance(String processInstanceId, String deleteReason);
  
  /**
   * 委托受理人
   * @param taskId 任务ID
   * @param userId 被委托人
   */
  void delegateTask(String taskId, String userId);
  
  /**
   * 任务认领
   * @param taskId 任务ID
   * @param userId 认领人ID
   */
  void claimTask(String taskId, String userId);
  
  /**
   * 设置受理人
   * @param taskId 任务ID
   * @param userId 受理人ID
   */
  void setAssignee(String taskId, String userId);
​
  /**
   * 获取任务审批人列表
   * @param taskId
   * @return
   */
  List getCandidate(String taskId);
  
  /**
   * 获取历史审批列表
   * @param assignee
   * @return
   */
  List getHistorys(String assignee);
  
  /**
   * 分页显示历史审批列表
   * @param example
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getHistorys(TaskExample example, int pageNo, int pageSize);
  
  /**
   * 根据业务编码分页显示历史审批列表
   * @param businessKey
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getHistorysByBusinessKey(String businessKey, int pageNo, int pageSize);
  
  /**
   * 获取历史实例列表
   * @param applicant
   * @return
   */
  List getHistoricProcessInstances(String applicant);
  
  /**
   * 分页显示历史实例列表
   * @param example
   * @param pageNo
   * @param pageSize
   * @return
   */
  Page getHistoricProcessInstances(ProcessInstanceExample example, int pageNo, int pageSize);
  
  /**
     * 根据Task中的流程实例的ID,来获取对应的流程实例
     * @param task 流程中的任务
     * @return
     */
  ProcessInstance getProcessInstanceByTask(Task task);
    
    /**
     * 根据历史Task中的流程实例的ID,来获取对应的历史流程实例
     * @param instanceId
     * @return
     */
  HistoricProcessInstance getHistoricProcessInstanceById(String instanceId);
    
    /**
     * 根据taskId获取变量值
     * @param taskId
     * @param variableName
     * @param variableClass
     * @return
     */
   T getProcessVariables(String taskId, String variableName, Class variableClass);
    
    /**
     * 根据taskId获取变量值
     * @param taskId
     * @param variableName
     * @return
     */
  Object getProcessVariables(String taskId, String variableName);
    
    /**
     * 根据实例ID获取历史变量值
     * @param processInstanceId
     * @param variableName
     * @param variableClass
     * @return
     */
   T getHistoricVariable(String processInstanceId, String variableName, Class variableClass);
    
    /**
     * 根据实例ID获取历史变量值
     * @param processInstanceId
     * @param variableName
     * @return
     */
  Object getHistoricVariable(String processInstanceId, String variableName);
    
    /**
     * 获取任务变量列表
     * @param processInstanceId
     * @param taskId
     * @return
     */
  List getHistoricVariables(String processInstanceId, String taskId);
  
  /**
   * 获取实例变量列表
   * @param processInstanceId
   * @return
   */
  List getHistoricVariables(String processInstanceId);
  
  /**
   * 获取任务的指定变量
   * @param taskId
   * @param variableName
   * @return
   */
  Object getTaskVariable(String taskId, String variableName);
  
  /**
   * 获取任务所有变量
   * @param taskId
   * @return
   */
  Map getTaskVariables(String taskId);
  
  /**
   * 设置流程变量
   * @param taskId
   * @param variables
   */
  void setProcessVariables(String taskId, Map variables);
  
  /**
   * 设置流程变量
   * @param taskId
   * @param variableName
   * @param value
   */
  void setProcessVariable(String taskId, String variableName, Object value);
  
  /**
   * 设置任务变量
   * @param taskId
   * @param variables
   */
  void setTaskVariables(String taskId, Map variables);
  
  /**
   * 设置任务变量
   * @param taskId
   * @param variableName
   * @param value
   */
  void setTaskVariable(String taskId, String variableName, Object value);
  
  /**
   * 获取任务审批批注列表
   * @param taskId
   * @return
   */
  List getTaskComments(String taskId);
  
  /**
   * 获取任务审批批注信息
   * @param taskId
   * @return
   */
  String getTaskComment(String taskId);
  
  /**
   * 添加任务批注
   * @param taskId
   * @param message
   */
  void addComment(String taskId, String message);
  
  /**
   * 获取实例流程图
   * @param instanceId
   * @return
   */
  InputStream getInstanceDiagram(String instanceId);
}
package cn.jia.workflow.service.impl;
​
import cn.jia.core.common.EsSecurityHandler;
import cn.jia.core.util.StringUtils;
import cn.jia.workflow.entity.DeploymentExample;
import cn.jia.workflow.entity.ProcessDefinitionExample;
import cn.jia.workflow.entity.ProcessInstanceExample;
import cn.jia.workflow.entity.TaskExample;
import cn.jia.workflow.service.WorkflowService;
import com.github.pagehelper.Page;
import org.camunda.bpm.engine.*;
import org.camunda.bpm.engine.history.*;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.repository.DeploymentQuery;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.repository.ProcessDefinitionQuery;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.IdentityLink;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.task.TaskQuery;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.instance.Process;
import org.camunda.bpm.model.bpmn.instance.*;
import org.camunda.bpm.model.bpmn.instance.bpmndi.*;
import org.camunda.bpm.model.bpmn.instance.dc.Bounds;
import org.camunda.bpm.model.bpmn.instance.di.Waypoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
​
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
​
@Service
public class WorkflowServiceImpl implements WorkflowService {
​
  @Autowired
  private RepositoryService repositoryService;
  @Autowired
  private RuntimeService runtimeService;
  @Autowired
  private TaskService taskService;
  @Autowired
  private HistoryService historyService;
  @Autowired
  private IdentityService identityService;
  
  @Override
  public void deployProcess(Deployment deployment, InputStream inputStream) {
    String clientId = EsSecurityHandler.clientId();
    repositoryService.createDeployment().addInputStream(deployment.getName()+".bpmn", inputStream).name(deployment.getName()).tenantId(clientId).deploy();
  }
  
  @Override
  public void deployProcess(Deployment deployment, ZipInputStream zipInputStream) {
    String clientId = EsSecurityHandler.clientId();
    repositoryService.createDeployment().addZipInputStream(zipInputStream).name(deployment.getName()).tenantId(clientId).deploy();
  }
  
  @Override
  public List getDeployment() {
    return repositoryService.createDeploymentQuery().tenantIdIn(EsSecurityHandler.clientId()).list();
  }
  
  @Override
  public Page getDeployment(DeploymentExample example, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    DeploymentQuery query = repositoryService.createDeploymentQuery().tenantIdIn(EsSecurityHandler.clientId());
    if(example != null){
      if(example.getName() != null){
        query.deploymentNameLike("%" + example.getName() + "%");
      }
    }
    query.orderByDeploymentTime().desc();
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
  public Deployment getDeploymentById(String deploymentId) {
    return repositoryService.createDeploymentQuery().tenantIdIn(EsSecurityHandler.clientId()).deploymentId(deploymentId).singleResult();
  }
  
  @Override
  public List getDeploymentResourceNames(String deploymentId) {
    return repositoryService.getDeploymentResourceNames(deploymentId);
  }
  
  @Override
  public InputStream getResourceAsStream(String deploymentId, String resourceName) {
    return repositoryService.getResourceAsStream(deploymentId, resourceName);
  }
  
  @Override
  public void deleteDeployment(String deploymentId) {
    repositoryService.deleteDeployment(deploymentId);
  }
  
  @Override
  public Page getProcessDefinition(ProcessDefinitionExample example, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().tenantIdIn(EsSecurityHandler.clientId());
    if(StringUtils.isNotEmpty(example.getKey())) {
      query.processDefinitionKeyLike("%" + example.getKey() + "%");
    }
    if(StringUtils.isNotEmpty(example.getDeploymentId())) {
      query.deploymentId(example.getDeploymentId());
    }
    if(StringUtils.isNotEmpty(example.getCategory())){
      query.processDefinitionCategoryLike("%" + example.getCategory() + "%");
    }
    if(StringUtils.isNotEmpty(example.getName())){
      query.processDefinitionNameLike("%" + example.getName() + "%");
    }
    if(StringUtils.isNotEmpty(example.getResourceName())){
      query.processDefinitionResourceNameLike("%" + example.getResourceName() + "%");
    }
    query.orderByDeploymentId().desc();
​
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
  public ProcessDefinition getProcessDefinitionById(String processDefinitionId) {
    return repositoryService.getProcessDefinition(processDefinitionId);
  }
  
  @Override
  public InputStream getProcessDiagram(String processDefinitionId) {
    return repositoryService.getProcessDiagram(processDefinitionId);
  }
  
  @Override
  public void activateProcessDefinition(String processDefinitionId) {
    repositoryService.activateProcessDefinitionById(processDefinitionId);
  }
  
  @Override
  public void suspendProcessDefinition(String processDefinitionId) {
    repositoryService.suspendProcessDefinitionById(processDefinitionId);
  }
​
  @Override
  public void startProcess(String processDefinitionKey, String businessKey, Map variables) {
    identityService.setAuthentication(String.valueOf(variables.get("applicant")), null, Collections.singletonList(EsSecurityHandler.clientId()));
    runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
  }
​
  @Override
  public List getTasks(String assignee) {
    return taskService.createTaskQuery().or().taskAssignee(assignee).taskCandidateUser(assignee).endOr().tenantIdIn(EsSecurityHandler.clientId()).list();
  }
  
  @Override
  public Page getTasks(TaskExample example, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    TaskQuery query = taskService.createTaskQuery();
    if(example != null) {
      if(StringUtils.isNotEmpty(example.getAssignee())) {
        query.taskAssignee(example.getAssignee());
      }
      if(StringUtils.isNotEmpty(example.getCandidateUser())) {
        query.taskCandidateUser(example.getCandidateUser());
      }
      if(StringUtils.isNotEmpty(example.getCandidateOrAssigned())) {
        query.or().taskAssignee(example.getCandidateOrAssigned()).taskCandidateUser(example.getCandidateOrAssigned()).endOr();
      }
      if(StringUtils.isNotEmpty(example.getDefinitionKey())) {
        query.processDefinitionKey(example.getDefinitionKey());
      }
      if(StringUtils.isNotEmpty(example.getDefinitionName())) {
        query.processDefinitionNameLike("%" + example.getDefinitionName() + "%");
      }
      if(StringUtils.isNotEmpty(example.getBusinessKey())) {
        query.processInstanceBusinessKeyLike("%" + example.getBusinessKey() + "%");
      }
      if(StringUtils.isNotEmpty(example.getProcessInstanceId())) {
        query.processInstanceId(example.getProcessInstanceId());
      }
      if(StringUtils.isNotEmpty(example.getApplicant())) {
        query.processVariableValueLike("applicant", "%" + example.getApplicant() + "%");
      }
    }
    query.tenantIdIn(EsSecurityHandler.clientId()).orderByTaskCreateTime().desc();
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
  public Task getTaskByBusinessKey(String businessKey, String assignee) {
    return taskService.createTaskQuery().processInstanceBusinessKey(businessKey).or().taskAssignee(assignee).taskCandidateUser(assignee).endOr().tenantIdIn(EsSecurityHandler.clientId()).singleResult();
  }
  
  @Override
  public List getTaskByBusinessKey(String businessKey) {
    return taskService.createTaskQuery().processInstanceBusinessKey(businessKey).tenantIdIn(EsSecurityHandler.clientId()).list();
  }
  
  @Override
  public Task getTaskById(String taskId) {
    return taskService.createTaskQuery().taskId(taskId).tenantIdIn(EsSecurityHandler.clientId()).singleResult();
  }
  
  @Override
  public List getTaskByProcessInstanceId(String processInstanceId) {
    return taskService.createTaskQuery().processInstanceId(processInstanceId).tenantIdIn(EsSecurityHandler.clientId()).list();
  }
​
  @Override
  public void completeTasks(String taskId, Map variables) {
    taskService.complete(taskId, variables);
  }
  
  @Override
  public void deleteProcessInstance(String processInstanceId, String deleteReason) {
        runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
  }
  
  @Override
  public void delegateTask(String taskId, String userId) {
    taskService.delegateTask(taskId, userId);
  }
  
  @Override
  public void claimTask(String taskId, String userId) {
    taskService.claim(taskId, userId);
  }
  
  @Override
  public void setAssignee(String taskId, String userId) {
    taskService.setAssignee(taskId, userId);
  }
​
  @Override
  public List getCandidate(String taskId) {
    List candidate = new ArrayList<>();
    List identityLinks = taskService.getIdentityLinksForTask(taskId);
    for(IdentityLink id : identityLinks){
      if("candidate".equals(id.getType())){
        candidate.add(id.getUserId());
      }
    }
    return candidate;
  }
​
  @Override
  public List getHistorys(String assignee) {
    return historyService.createHistoricTaskInstanceQuery().taskAssignee(assignee).tenantIdIn(EsSecurityHandler.clientId()).finished().list();
  }
  
  @Override
  public Page getHistorys(TaskExample example, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
    if(example != null) {
      if(StringUtils.isNotEmpty(example.getAssignee())) {
        query = query.taskAssignee(example.getAssignee());
      }
      if(StringUtils.isNotEmpty(example.getDefinitionKey())) {
        query.processDefinitionKey(example.getDefinitionKey());
      }
      if(StringUtils.isNotEmpty(example.getDefinitionName())) {
        query.processDefinitionName(example.getDefinitionName());
      }
      if(StringUtils.isNotEmpty(example.getBusinessKey())) {
        query.processInstanceBusinessKeyLike("%" + example.getBusinessKey() + "%");
      }
      if(StringUtils.isNotEmpty(example.getProcessInstanceId())) {
        query.processInstanceId(example.getProcessInstanceId());
      }
      if(StringUtils.isNotEmpty(example.getApplicant())) {
        query.processVariableValueEquals("applicant", example.getApplicant());
      }
    }
    
    query = query.tenantIdIn(EsSecurityHandler.clientId()).finished().orderByTaskDueDate().desc();
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
  public Page getHistorysByBusinessKey(String businessKey, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().processInstanceBusinessKey(businessKey).tenantIdIn(EsSecurityHandler.clientId()).finished().orderByHistoricTaskInstanceEndTime().asc();
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
  public List getHistoricProcessInstances(String applicant) {
    return historyService.createHistoricProcessInstanceQuery().startedBy(applicant).tenantIdIn(EsSecurityHandler.clientId()).list();
  }
  
  @Override
  public Page getHistoricProcessInstances(ProcessInstanceExample example, int pageNo, int pageSize) {
    Page page = new Page<>(pageNo, pageSize);
    HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
    if(example != null) {
      if(StringUtils.isNotEmpty(example.getApplicant())) {
        query.startedBy(example.getApplicant());
      }
      if(StringUtils.isNotEmpty(example.getDefinitionKey())) {
        query.processDefinitionKey(example.getDefinitionKey());
      }
      if(StringUtils.isNotEmpty(example.getDefinitionName())) {
        query.processDefinitionName(example.getDefinitionName());
      }
      if(example.getStartedBefore() != null) {
        query.startedBefore(example.getStartedBefore());
      }
      if(example.getStartedAfter() != null) {
        query.startedAfter(example.getStartedAfter());
      }
      if(example.getFinishedBefore() != null) {
        query.finishedBefore(example.getFinishedBefore());
      }
      if(example.getFinishedAfter() != null) {
        query.finishedAfter(example.getFinishedAfter());
      }
      if(StringUtils.isNotEmpty(example.getBusinessKey())) {
        query.processInstanceBusinessKey(example.getBusinessKey());
      }
    }
    
    query.tenantIdIn(EsSecurityHandler.clientId()).orderByProcessInstanceStartTime().desc();
    page.setTotal(query.count());
    page.addAll(query.listPage((pageNo - 1) * pageSize, pageSize));
    return page;
  }
  
  @Override
    public ProcessInstance getProcessInstanceByTask(Task task) {
        //得到当前任务的流程
    return runtimeService.createProcessInstanceQuery().tenantIdIn(EsSecurityHandler.clientId())
        .processInstanceId(task.getProcessInstanceId()).singleResult();
    }
  
  @Override
    public HistoricProcessInstance getHistoricProcessInstanceById(String instanceId) {
        //得到当前任务的流程
    return historyService.createHistoricProcessInstanceQuery().tenantIdIn(EsSecurityHandler.clientId())
                .processInstanceId(instanceId).singleResult();
    }
  
  @Override
  @SuppressWarnings("unchecked")
  public  T getProcessVariables(String taskId, String variableName, Class variableClass) {
    return (T)taskService.getVariable(taskId, variableName);
  }
  
  @Override
  public Object getProcessVariables(String taskId, String variableName) {
    return taskService.getVariable(taskId, variableName);
  }
  
  @SuppressWarnings("unchecked")
  @Override
  public  T getHistoricVariable(String processInstanceId, String variableName, Class variableClass) {
    HistoricVariableInstance instance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(variableName).singleResult();
    if(instance != null && instance.getValue() != null) {
      return (T) instance.getValue();
    }else {
      return null;
    }
  }
  
  @Override
  public Object getHistoricVariable(String processInstanceId, String variableName) {
    HistoricVariableInstance instance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(variableName).singleResult();
    if(instance != null && instance.getValue() != null) {
      return instance.getValue();
    }else {
      return null;
    }
  }
  
  @Override
  public List getHistoricVariables(String processInstanceId, String taskId) {
    return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).taskIdIn(taskId).list();
  }
  
  @Override
  public List getHistoricVariables(String processInstanceId) {
    return historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list();
  }
  
  @Override
  public Object getTaskVariable(String taskId, String variableName) {
    return taskService.getVariable(taskId, variableName);
  }
  
  @Override
  public Map getTaskVariables(String taskId) {
    return taskService.getVariables(taskId);
  }
​
  @Override
  public void setProcessVariables(String taskId, Map variables) {
    taskService.setVariables(taskId, variables);
  }
  
  @Override
  public void setProcessVariable(String taskId, String variableName, Object value) {
    taskService.setVariable(taskId, variableName, value);
  }
  
  @Override
  public void setTaskVariables(String taskId, Map variables) {
    taskService.setVariablesLocal(taskId, variables);
  }
  
  @Override
  public void setTaskVariable(String taskId, String variableName, Object value) {
    taskService.setVariableLocal(taskId, variableName, value);
  }
  
  @Override
  public List getTaskComments(String taskId) {
    return taskService.getTaskComments(taskId);
  }
  
  @Override
  public String getTaskComment(String taskId) {
    List comment = new ArrayList<>();
    List commentList = taskService.getTaskComments(taskId);
    for(Comment c : commentList) {
      comment.add(c.getFullMessage());
    }
    return String.join(",", comment);
  }
  
  @Override
  public void addComment(String taskId, String message) {
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    taskService.createComment(taskId, task.getProcessInstanceId(), message);
  }
  
  @Override
  public InputStream getInstanceDiagram(String instanceId) {
    return null;
//        try {
//            // 获取历史流程实例
//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult();
//
//            // 获取流程中已经执行的节点,按照执行先后顺序排序
//            List historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).orderByHistoricActivityInstanceId().asc().list();
//
//            // 构造已执行的节点ID集合
//            List executedActivityIdList = new ArrayList<>();
//            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
//                executedActivityIdList.add(activityInstance.getActivityId());
//            }
//
//            // 获取bpmnModel
//            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
//            // 获取流程已发生流转的线ID集合
//            List flowIds = this.getExecutedFlows(bpmnModel, historicActivityInstanceList);
//
//            // 使用默认配置获得流程图表生成器,并生成追踪图片字符流
//            ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
//      return processDiagramGenerator.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds, "宋体", "微软雅黑", "黑体", null, 2.0);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return null;
//        }
    }
  
//  private List getExecutedFlows(BpmnModel bpmnModel, List historicActivityInstances) {
//        // 流转线ID集合
//        List flowIdList = new ArrayList<>();
//        // 全部活动实例
//        List historicFlowNodeList = new LinkedList<>();
//        // 已完成的历史活动节点
//        List finishedActivityInstanceList = new LinkedList<>();
//        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
//            historicFlowNodeList.add((FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true));
//            if (historicActivityInstance.getEndTime() != null) {
//                finishedActivityInstanceList.add(historicActivityInstance);
//            }
//        }
//
//        // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
//        FlowNode currentFlowNode;
//        for (HistoricActivityInstance currentActivityInstance : finishedActivityInstanceList) {
//            // 获得当前活动对应的节点信息及outgoingFlows信息
//            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
//            List sequenceFlowList = currentFlowNode.getOutgoingFlows();
//
//            /*
//              遍历outgoingFlows并找到已已流转的
//              满足如下条件认为已已流转:
//              1.当前节点是并行网关或包含网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
//              2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最近的流转节点视为有效流转
//             */
//            FlowNode targetFlowNode;
//            if (BpmsActivityTypeEnum.PARALLEL_GATEWAY.getType().equals(currentActivityInstance.getActivityType())
//                    || BpmsActivityTypeEnum.INCLUSIVE_GATEWAY.getType().equals(currentActivityInstance.getActivityType())) {
//                // 遍历历史活动节点,找到匹配Flow目标节点的
//                for (SequenceFlow sequenceFlow : sequenceFlowList) {
//                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
//                    if (historicFlowNodeList.contains(targetFlowNode)) {
//                        flowIdList.add(sequenceFlow.getId());
//                    }
//                }
//            } else {
//                List> tempMapList = new LinkedList<>();
//                // 遍历历史活动节点,找到匹配Flow目标节点的
//                for (SequenceFlow sequenceFlow : sequenceFlowList) {
//                    for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
//                        if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
//                            tempMapList.add(DataUtil.toMap("flowId", sequenceFlow.getId(), "activityStartTime", String.valueOf(historicActivityInstance.getStartTime().getTime())));
//                        }
//                    }
//                }
//
//                // 遍历匹配的集合,取得开始时间最早的一个
//                long earliestStamp = 0L;
//                String flowId = null;
//                for (Map map : tempMapList) {
//                    long activityStartTime = Long.valueOf(map.get("activityStartTime"));
//                    if (earliestStamp == 0 || earliestStamp >= activityStartTime) {
//                        earliestStamp = activityStartTime;
//                        flowId = map.get("flowId");
//                    }
//                }
//                flowIdList.add(flowId);
//            }
//        }
//        return flowIdList;
//    }
​
​
  public void generateProcess() throws IOException {
    BpmnModelInstance modelInstance = Bpmn.createEmptyModel();
    Definitions definitions = modelInstance.newInstance(Definitions.class);
    definitions.setTargetNamespace("http://camunda.org/examples");
    modelInstance.setDefinitions(definitions);
​
    // create the process
    Process process = modelInstance.newInstance(Process.class);
    process.setAttributeValue("id", "process-one-task", true);
    definitions.addChildElement(process);
​
    BpmnDiagram diagram = modelInstance.newInstance(BpmnDiagram.class);
    BpmnPlane plane = modelInstance.newInstance(BpmnPlane.class);
    plane.setBpmnElement(process);
    diagram.setBpmnPlane(plane);
    definitions.addChildElement(diagram);
​
    // create start event, user task and end event
    StartEvent startEvent = createElement(modelInstance, process, "start", "Di generation wanted",
        StartEvent.class, plane, 15, 15, 50, 50, true);
​
    UserTask userTask = createElement(modelInstance, process, "userTask", "Generate Model with DI",
        UserTask.class, plane, 100, 0, 80, 100, false);
​
    createSequenceFlow(modelInstance, process, startEvent, userTask, plane, 65, 40, 100, 40);
​
    EndEvent endEvent = createElement(modelInstance, process, "end", "DI generation completed",
        EndEvent.class, plane, 250, 15, 50, 50, true);
​
    createSequenceFlow(modelInstance, process, userTask, endEvent, plane, 200, 40, 250, 40);
​
    // validate and write model to file
    Bpmn.validateModel(modelInstance);
    File file = File.createTempFile("bpmn-model-api-", ".bpmn");
    Bpmn.writeModelToFile(file, modelInstance);
​
  }
​
  private  T createElement(BpmnModelInstance modelInstance, BpmnModelElementInstance parentElement,
                                 String id, String name, Class elementClass, BpmnPlane plane,
                                 double x, double y, double heigth, double width, boolean withLabel) {
    T element = modelInstance.newInstance(elementClass);
    element.setAttributeValue("id", id, true);
    element.setAttributeValue("name", name, false);
    parentElement.addChildElement(element);
​
    BpmnShape bpmnShape = modelInstance.newInstance(BpmnShape.class);
    bpmnShape.setBpmnElement((BaseElement) element);
​
    Bounds bounds = modelInstance.newInstance(Bounds.class);
    bounds.setX(x);
    bounds.setY(y);
    bounds.setHeight(heigth);
    bounds.setWidth(width);
    bpmnShape.setBounds(bounds);
​
    if (withLabel) {
      BpmnLabel bpmnLabel = modelInstance.newInstance(BpmnLabel.class);
      Bounds labelBounds = modelInstance.newInstance(Bounds.class);
      labelBounds.setX(x);
      labelBounds.setY(y + heigth);
      labelBounds.setHeight(heigth);
      labelBounds.setWidth(width);
      bpmnLabel.addChildElement(labelBounds);
      bpmnShape.addChildElement(bpmnLabel);
    }
    plane.addChildElement(bpmnShape);
​
    return element;
  }
​
  private SequenceFlow createSequenceFlow(BpmnModelInstance modelInstance, Process process, FlowNode from, FlowNode to, BpmnPlane plane,
                      int... waypoints) {
    String identifier = from.getId() + "-" + to.getId();
    SequenceFlow sequenceFlow = modelInstance.newInstance(SequenceFlow.class);
    sequenceFlow.setAttributeValue("id", identifier, true);
    process.addChildElement(sequenceFlow);
    sequenceFlow.setSource(from);
    from.getOutgoing().add(sequenceFlow);
    sequenceFlow.setTarget(to);
    to.getIncoming().add(sequenceFlow);
​
    BpmnEdge bpmnEdge = modelInstance.newInstance(BpmnEdge.class);
    bpmnEdge.setBpmnElement(sequenceFlow);
    for (int i = 0; i < waypoints.length / 2; i++) {
      double waypointX = waypoints[i*2];
      double waypointY = waypoints[i*2+1];
      Waypoint wp = modelInstance.newInstance(Waypoint.class);
      wp.setX(waypointX);
      wp.setY(waypointY);
      bpmnEdge.addChildElement(wp);
    }
    plane.addChildElement(bpmnEdge);
​
    return sequenceFlow;
  }
​
}

再贴一个我常用的Listener

package cn.jia.workflow.listener;
​
import cn.jia.core.common.EsSecurityHandler;
import cn.jia.core.entity.JSONResult;
import cn.jia.core.util.*;
import cn.jia.workflow.common.ErrorConstants;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.delegate.*;
import org.camunda.bpm.engine.impl.el.JuelExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
​
import java.util.Map;
​
/**
 * Rest接口调用通用方法
 * @author chcbz
 * @date 2018年9月11日 下午3:37:55
 */
@Slf4j
@Service
public class RestListener implements ExecutionListener, TaskListener {
  
  private static final long serialVersionUID = -507889727531125820L;
  
  private JuelExpression url;
  private JuelExpression method;
  private JuelExpression params;
  @Autowired
  @Qualifier("singleRestTemplate")
  private RestTemplate restTemplate;
  @Autowired
  private TaskService taskService;
​
  @Override
  public void notify(DelegateTask delegateTask) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//    OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails();
//    headers.set("Authorization", "Bearer " + details.getTokenValue());
    String rqurl = fixedValueToString(url, delegateTask);
    String random = DataUtil.getRandom(false, 16);
    rqurl = HttpUtil.addUrlValue(rqurl, "nonce", random);
    String signature = MD5Util.str2Base32MD5(MD5Util.str2Base32MD5(random)+EsSecurityHandler.clientId());
    rqurl = HttpUtil.addUrlValue(rqurl, "signature", signature);
    String businessKey = String.valueOf(taskService.getVariable(delegateTask.getId(), "businessKey"));
    rqurl = HttpUtil.addUrlValue(rqurl, "businessKey", businessKey);
    String assignee = delegateTask.getAssignee();
    rqurl = HttpUtil.addUrlValue(rqurl, "assignee", assignee);
​
    String paramsStr = fixedValueToString(params, delegateTask);
    if(StringUtils.isNotEmpty(paramsStr)){
      Map paramsMap = JSONUtil.jsonToMap(paramsStr);
      if(paramsMap != null){
        for (String paramsKey : paramsMap.keySet()) {
          rqurl = HttpUtil.addUrlValue(rqurl, paramsKey, String.valueOf(paramsMap.get(paramsKey)));
        }
      }
​
    }
​
//    String candidate = "";
//    Set candidates = delegateTask.getCandidates();
//    for(IdentityLink id : candidates){
//      candidate += "," + id.getUserId();
//    }
//    rqurl = HttpUtil.addUrlValue(rqurl, "candidate", StringUtils.isEmpty(candidate) ? "" : candidate.substring(1));
    log.info("======================rqurl: " + rqurl);
    log.info("======================method: " + fixedValueToString(method, delegateTask));
    log.info("======================params: " + paramsStr);
    HttpEntity entity = new HttpEntity<>(fixedValueToString(params, delegateTask), headers);
    JSONResult result = restTemplate.exchange(rqurl, HttpMethod.resolve(fixedValueToString(method, delegateTask)), entity, JSONResult.class).getBody();
    if(!ErrorConstants.SUCCESS.equals(result.getCode())) {
      log.error(result.getMsg());
    }
  }
​
  @Override
  public void notify(DelegateExecution execution) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//    OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails();
//    headers.set("Authorization", "Bearer " + details.getTokenValue());
    String rqurl = fixedValueToString(url, execution);
    String random = DataUtil.getRandom(false, 16);
    rqurl = HttpUtil.addUrlValue(rqurl, "nonce", random);
    String signature = MD5Util.str2Base32MD5(MD5Util.str2Base32MD5(random)+EsSecurityHandler.clientId());
    rqurl = HttpUtil.addUrlValue(rqurl, "signature", signature);
    String businessKey = execution.getBusinessKey();
    rqurl = HttpUtil.addUrlValue(rqurl, "businessKey", businessKey);
    HttpEntity entity = new HttpEntity<>(fixedValueToString(params, execution), headers);
    JSONResult result = restTemplate.exchange(rqurl, HttpMethod.resolve(fixedValueToString(method, execution)), entity, JSONResult.class).getBody();
    if(!ErrorConstants.SUCCESS.equals(result.getCode())) {
      log.error(result.getMsg());
    }
  }
  
  private String fixedValueToString(Expression fixedValue, VariableScope variableScope) {
    if(fixedValue == null) {
      return null;
    }
    return fixedValue.getValue(variableScope).toString();
  }
​
}

再贴一个BPMN吧



  
    
    
    
      
        
          
            https://api.mydomain.com/car/notify
          
          
            GET
          
          
            {"candidate":"${reviewers}","type":"Vehicle_reservation_approval"}
          
        
      
    
    
    
    
      flow4
    
    
      
        
          
            https://api.mydomain.com/car/complete/${businessKey}
          
          
            GET
          
          
            {}
          
        
      
      ${pass}
    
    
      
        
          
            https://api.mydomain.com/car/reject/${businessKey}
          
          
            GET
          
          
            {}
          
        
      
    
  
  
    
      
        
        
          
        
      
      
        
        
          
        
      
      
        
        
          
        
      
      
        
        
          
        
      
      
        
        
        
          
        
      
      
        
        
        
          
        
      
      
        
        
        
          
        
      
      
        
        
        
        
        
          
        
      
    
  

 

最后

至此,项目已经可以正常地跑起来,迁移工作也完成了,但是其实还有个问题没有解决,就是现在还无法自动生成实例流程图,官方没有给出相应例子,留待后续处理。

我把项目代码放到github上,供大家参考,只是由于采用的是springcloud,并且依赖了一些私有jar包,所以无法单独跑起来。

https://github.com/chcbz/jia-api-workflow

 

参考文章:

https://blog.csdn.net/qq_30739519/article/details/86583765(Camunda/Flowable/Activiti技术发展史)

https://blog.csdn.net/skayliu/article/details/89048225(从Activiti切换到Camunda的5个理由)

http://blog.camunda.com/post/2016/10/migrate-from-activiti-to-camunda/(How to migrate from Activiti 5.21 to Camunda BPM 7.5)

你可能感兴趣的:(java,activiti,camunda,springboot,bpmn2)