提交 f4900fd9 编写于 作者: M meyerd

ACT-1074 Support suspension of JobExecution for ProcessDefinitions and ProcessInstances

上级 7bfb6453
......@@ -73,4 +73,38 @@ public interface RepositoryService {
/** Query process definitions. */
DeploymentQuery createDeploymentQuery();
/**
* Suspends the process definition with the given id.
*
* If a process definition is in state suspended, activiti will not
* execute jobs (timers, messages) associated with any process instance of the given definition.
*
* @throws ActivitiException if no such processDefinition can be found or if the process definition is already in state suspended.
*/
void suspendProcessDefinitionById(String processDefinitionId);
/**
* Suspends the process definition with the given key (=id in the bpmn20.xml file).
*
* If a process definition is in state suspended, activiti will not
* execute jobs (timers, messages) associated with any process instance of the given definition.
*
* @throws ActivitiException if no such processDefinition can be found or if the process definition is already in state suspended.
*/
void suspendProcessDefinitionByKey(String processDefinitionKey);
/**
* Activates the process definition with the given id.
*
* @throws ActivitiException if no such processDefinition can be found or if the process definition is already in state active.
*/
void activateProcessDefinitionById(String processDefinitionId);
/**
* Activates the process definition with the given key (=id in the bpmn20.xml file).
*
* @throws ActivitiException if no such processDefinition can be found or if the process definition is already in state active.
*/
void activateProcessDefinitionByKey(String processDefinitionKey);
}
......@@ -254,4 +254,30 @@ public interface RuntimeService {
* to query process instances.
*/
ProcessInstanceQuery createProcessInstanceQuery();
/**
* Suspends the process instance with the given id.
*
* If a process instance is in state suspended, activiti will not
* execute jobs (timers, messages) associated with this instance.
*
* If you have a process instance hierarchy, suspending
* one process instance form the hierarchy will not suspend other
* process instances form that hierarchy.
*
* @throws ActivitiException if no such processInstance can be found or if the process instance is already in state suspended.
*/
void suspendProcessInstanceById(String processInstanceId);
/**
* Activates the process instance with the given id.
*
* If you have a process instance hierarchy, suspending
* one process instance form the hierarchy will not suspend other
* process instances form that hierarchy.
*
* @throws ActivitiException if no such processInstance can be found or if the process instance is already in state active.
*/
void activateProcessInstanceById(String processInstanceId);
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ import java.util.List;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ExecutionQuery;
......@@ -24,6 +25,7 @@ import org.activiti.engine.runtime.ExecutionQuery;
/**
* @author Joram Barrez
* @author Frederik Heremans
* @author Daniel Meyer
*/
public class ExecutionQueryImpl extends ExecutionVariableQueryImpl<ExecutionQuery, Execution>
implements ExecutionQuery {
......@@ -38,6 +40,7 @@ public class ExecutionQueryImpl extends ExecutionVariableQueryImpl<ExecutionQuer
// Not used by end-users, but needed for dynamic ibatis query
protected String superProcessInstanceId;
protected String subProcessInstanceId;
protected SuspensionState suspensionState;
public ExecutionQueryImpl() {
}
......@@ -159,5 +162,11 @@ public class ExecutionQueryImpl extends ExecutionVariableQueryImpl<ExecutionQuer
}
public String getSubProcessInstanceId() {
return subProcessInstanceId;
}
public SuspensionState getSuspensionState() {
return suspensionState;
}
public void setSuspensionState(SuspensionState suspensionState) {
this.suspensionState = suspensionState;
}
}
......@@ -18,6 +18,7 @@ import java.util.List;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
......@@ -25,6 +26,7 @@ import org.activiti.engine.repository.ProcessDefinitionQuery;
/**
* @author Tom Baeyens
* @author Joram Barrez
* @author Daniel Meyer
*/
public class ProcessDefinitionQueryImpl extends AbstractQuery<ProcessDefinitionQuery, ProcessDefinition>
implements ProcessDefinitionQuery {
......@@ -42,6 +44,7 @@ public class ProcessDefinitionQueryImpl extends AbstractQuery<ProcessDefinitionQ
protected String resourceNameLike;
protected Integer version;
protected boolean latest = false;
protected SuspensionState suspensionState;
public ProcessDefinitionQueryImpl() {
}
......@@ -146,6 +149,16 @@ public class ProcessDefinitionQueryImpl extends AbstractQuery<ProcessDefinitionQ
return this;
}
public ProcessDefinitionQuery active() {
this.suspensionState = SuspensionState.ACTIVE;
return this;
}
public ProcessDefinitionQuery suspended() {
this.suspensionState = SuspensionState.SUSPENDED;
return this;
}
//sorting ////////////////////////////////////////////
public ProcessDefinitionQuery orderByDeploymentId() {
......@@ -234,5 +247,11 @@ public class ProcessDefinitionQueryImpl extends AbstractQuery<ProcessDefinitionQ
}
public String getResourceNameLike() {
return resourceNameLike;
}
public SuspensionState getSuspensionState() {
return suspensionState;
}
public void setSuspensionState(SuspensionState suspensionState) {
this.suspensionState = suspensionState;
}
}
......@@ -20,6 +20,7 @@ import java.util.Set;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
......@@ -29,6 +30,7 @@ import org.activiti.engine.runtime.ProcessInstanceQuery;
* @author Joram Barrez
* @author Frederik Heremans
* @author Falko Menge
* @author Daniel Meyer
*/
public class ProcessInstanceQueryImpl extends ExecutionVariableQueryImpl<ProcessInstanceQuery, ProcessInstance> implements ProcessInstanceQuery, Serializable {
......@@ -40,6 +42,7 @@ public class ProcessInstanceQueryImpl extends ExecutionVariableQueryImpl<Process
protected String processDefinitionKey;
protected String superProcessInstanceId;
protected String subProcessInstanceId;
protected SuspensionState suspensionState;
// Unused, see dynamic query
protected String activityId;
......@@ -133,6 +136,16 @@ public class ProcessInstanceQueryImpl extends ExecutionVariableQueryImpl<Process
return this;
}
public ProcessInstanceQuery active() {
this.suspensionState = SuspensionState.ACTIVE;
return this;
}
public ProcessInstanceQuery suspended() {
this.suspensionState = SuspensionState.SUSPENDED;
return this;
}
//results /////////////////////////////////////////////////////////////////
public long executeCount(CommandContext commandContext) {
......@@ -179,5 +192,11 @@ public class ProcessInstanceQueryImpl extends ExecutionVariableQueryImpl<Process
}
public String getSubProcessInstanceId() {
return subProcessInstanceId;
}
public SuspensionState getSuspensionState() {
return suspensionState;
}
public void setSuspensionState(SuspensionState suspensionState) {
this.suspensionState = suspensionState;
}
}
......@@ -17,11 +17,14 @@ import java.io.InputStream;
import java.util.List;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.cmd.ActivateProcessDefinitionCmd;
import org.activiti.engine.impl.cmd.ActivateProcessInstanceCmd;
import org.activiti.engine.impl.cmd.DeleteDeploymentCmd;
import org.activiti.engine.impl.cmd.DeployCmd;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.cmd.GetDeploymentResourceCmd;
import org.activiti.engine.impl.cmd.GetDeploymentResourceNamesCmd;
import org.activiti.engine.impl.cmd.SuspendProcessDefinitionCmd;
import org.activiti.engine.impl.pvm.ReadOnlyProcessDefinition;
import org.activiti.engine.impl.repository.DeploymentBuilderImpl;
import org.activiti.engine.repository.Deployment;
......@@ -75,5 +78,23 @@ public class RepositoryServiceImpl extends ServiceImpl implements RepositoryServ
public ReadOnlyProcessDefinition getDeployedProcessDefinition(String processDefinitionId) {
return commandExecutor.execute(new GetDeploymentProcessDefinitionCmd(processDefinitionId));
}
public void suspendProcessDefinitionById(String processDefinitionId) {
commandExecutor.execute(new SuspendProcessDefinitionCmd(processDefinitionId, null));
}
public void suspendProcessDefinitionByKey(String processDefinitionKey) {
commandExecutor.execute(new SuspendProcessDefinitionCmd(null, processDefinitionKey));
}
public void activateProcessDefinitionById(String processDefinitionId) {
commandExecutor.execute(new ActivateProcessDefinitionCmd(processDefinitionId, null));
}
public void activateProcessDefinitionByKey(String processDefinitionKey) {
commandExecutor.execute(new ActivateProcessDefinitionCmd(null, processDefinitionKey));
}
}
......@@ -20,20 +20,23 @@ import java.util.Map;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.form.FormData;
import org.activiti.engine.impl.cmd.ActivateProcessInstanceCmd;
import org.activiti.engine.impl.cmd.DeleteProcessInstanceCmd;
import org.activiti.engine.impl.cmd.FindActiveActivityIdsCmd;
import org.activiti.engine.impl.cmd.GetStartFormCmd;
import org.activiti.engine.impl.cmd.GetExecutionVariableCmd;
import org.activiti.engine.impl.cmd.GetExecutionVariablesCmd;
import org.activiti.engine.impl.cmd.GetStartFormCmd;
import org.activiti.engine.impl.cmd.SetExecutionVariablesCmd;
import org.activiti.engine.impl.cmd.SignalCmd;
import org.activiti.engine.impl.cmd.StartProcessInstanceCmd;
import org.activiti.engine.impl.cmd.SuspendProcessInstanceCmd;
import org.activiti.engine.runtime.ExecutionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
/**
* @author Tom Baeyens
* @author Daniel Meyer
*/
public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {
......@@ -142,4 +145,12 @@ public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {
public FormData getFormInstanceById(String processDefinitionId) {
return commandExecutor.execute(new GetStartFormCmd(processDefinitionId));
}
public void suspendProcessInstanceById(String processInstanceId) {
commandExecutor.execute(new SuspendProcessInstanceCmd(processInstanceId));
}
public void activateProcessInstanceById(String processInstanceId) {
commandExecutor.execute(new ActivateProcessInstanceCmd(processInstanceId));
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionManager;
/**
*
* @author Daniel Meyer
*/
public abstract class AbstractSetProcessDefinitionStateCmd implements Command<Void> {
protected final String processDefinitionId;
private final String processDefinitionKey;
public AbstractSetProcessDefinitionStateCmd(String processDefinitionId, String processDefinitionKey) {
this.processDefinitionId = processDefinitionId;
this.processDefinitionKey = processDefinitionKey;
}
public Void execute(CommandContext commandContext) {
if(processDefinitionId == null && processDefinitionKey == null) {
throw new ActivitiException("Process definition id / key cannot be null");
}
ProcessDefinitionEntity processDefinitionEntity = null;
ProcessDefinitionManager processDefinitionManager = commandContext.getProcessDefinitionManager();
if(processDefinitionId == null) {
processDefinitionEntity = processDefinitionManager.findLatestProcessDefinitionByKey(processDefinitionKey);
if(processDefinitionEntity == null) {
throw new ActivitiException("Cannot find process definition for key '"+processDefinitionKey+"'");
}
} else {
processDefinitionEntity = processDefinitionManager.findLatestProcessDefinitionById(processDefinitionId);
if(processDefinitionEntity == null) {
throw new ActivitiException("Cannot find process definition for id '"+processDefinitionId+"'");
}
}
setState(processDefinitionEntity);
return null;
}
protected abstract void setState(ProcessDefinitionEntity processDefinitionEntity);
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.impl.persistence.entity.SuspensionState.SuspensionStateUtil;
/**
*
* @author Daniel Meyer
*/
public abstract class AbstractSetProcessInstanceStateCmd implements Command<Void> {
protected final String executionId;
public AbstractSetProcessInstanceStateCmd(String executionId) {
this.executionId = executionId;
}
public Void execute(CommandContext commandContext) {
if(executionId == null) {
throw new ActivitiException("ProcessInstanceId cannot be null.");
}
ExecutionEntity executionEntity = commandContext.getExecutionManager()
.findExecutionById(executionId);
if(executionEntity == null) {
throw new ActivitiException("Cannot find processInstance for id '"+executionId+"'.");
}
if(!executionEntity.isProcessInstance()) {
throw new ActivitiException("Cannot set suspension state for execution '"+executionId+"': not a process instance.");
}
SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());
return null;
}
protected abstract SuspensionState getNewState();
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.impl.persistence.entity.SuspensionState.SuspensionStateUtil;
/**
*
* @author Daniel Meyer
*/
public class ActivateProcessDefinitionCmd extends AbstractSetProcessDefinitionStateCmd {
public ActivateProcessDefinitionCmd(String processDefinitionId, String processDefinitionKey) {
super(processDefinitionId, processDefinitionKey);
}
protected void setState(ProcessDefinitionEntity processDefinitionEntity) {
SuspensionStateUtil.setSuspensionState(processDefinitionEntity, SuspensionState.ACTIVE);
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
/**
*
* @author Daniel Meyer
*/
public class ActivateProcessInstanceCmd extends AbstractSetProcessInstanceStateCmd {
public ActivateProcessInstanceCmd(String executionId) {
super(executionId);
}
@Override
protected SuspensionState getNewState() {
return SuspensionState.ACTIVE;
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.impl.persistence.entity.SuspensionState.SuspensionStateUtil;
/**
*
* @author Daniel Meyer
*/
public class SuspendProcessDefinitionCmd extends AbstractSetProcessDefinitionStateCmd {
public SuspendProcessDefinitionCmd(String processDefinitionId, String processDefinitionKey) {
super(processDefinitionId, processDefinitionKey);
}
protected void setState(ProcessDefinitionEntity processDefinitionEntity) {
SuspensionStateUtil.setSuspensionState(processDefinitionEntity, SuspensionState.SUSPENDED);
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.cmd;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
/**
*
* @author Daniel Meyer
*/
public class SuspendProcessInstanceCmd extends AbstractSetProcessInstanceStateCmd {
public SuspendProcessInstanceCmd(String executionId) {
super(executionId);
}
@Override
protected SuspensionState getNewState() {
return SuspensionState.SUSPENDED;
}
}
......@@ -142,6 +142,7 @@ public class ExecutionEntity extends VariableScopeImpl implements ActivityExecut
protected String id = null;
protected int revision = 1;
protected int suspensionState = SuspensionState.ACTIVE.getStateCode();
/**
* persisted reference to the processDefinition.
......@@ -942,6 +943,7 @@ public class ExecutionEntity extends VariableScopeImpl implements ActivityExecut
if (forcedUpdate) {
persistentState.put("forcedUpdate", Boolean.TRUE);
}
persistentState.put("suspensionState", this.suspensionState);
return persistentState;
}
......@@ -1061,4 +1063,16 @@ public class ExecutionEntity extends VariableScopeImpl implements ActivityExecut
public boolean isDeleteRoot() {
return deleteRoot;
}
public int getSuspensionState() {
return suspensionState;
}
public void setSuspensionState(int suspensionState) {
this.suspensionState = suspensionState;
}
public boolean isSuspended() {
return suspensionState == SuspensionState.SUSPENDED.getStateCode();
}
}
......@@ -14,6 +14,7 @@ package org.activiti.engine.impl.persistence.entity;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
......@@ -34,12 +35,14 @@ import org.activiti.engine.repository.ProcessDefinition;
/**
* @author Tom Baeyens
* @author Daniel Meyer
*/
public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements ProcessDefinition, PersistentObject {
private static final long serialVersionUID = 1L;
protected String key;
protected int revision = 1;
protected int version;
protected String category;
protected String deploymentId;
......@@ -50,6 +53,7 @@ public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements Pr
protected boolean isGraphicalNotationDefined;
protected Map<String, TaskDefinition> taskDefinitions;
protected boolean hasStartFormKey;
protected int suspensionState = SuspensionState.ACTIVE.getStateCode();
public ProcessDefinitionEntity() {
super(null);
......@@ -131,7 +135,9 @@ public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements Pr
// getters and setters //////////////////////////////////////////////////////
public Object getPersistentState() {
return ProcessDefinitionEntity.class;
Map<String, Object> persistentState = new HashMap<String, Object>();
persistentState.put("suspensionState", this.suspensionState);
return persistentState;
}
public String getKey() {
......@@ -238,4 +244,27 @@ public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements Pr
this.isGraphicalNotationDefined = isGraphicalNotationDefined;
}
public int getRevision() {
return revision;
}
public void setRevision(int revision) {
this.revision = revision;
}
public int getRevisionNext() {
return revision+1;
}
public int getSuspensionState() {
return suspensionState;
}
public void setSuspensionState(int suspensionState) {
this.suspensionState = suspensionState;
}
public boolean isSuspended() {
return suspensionState == SuspensionState.SUSPENDED.getStateCode();
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.impl.persistence.entity;
import org.activiti.engine.ActivitiException;
/**
* Contains a predefined set of states for process definitions and process instances
*
* @author Daniel Meyer
*/
public interface SuspensionState {
SuspensionState ACTIVE = new SuspensionStateImpl(1, "active");
SuspensionState SUSPENDED = new SuspensionStateImpl(2, "suspended");
int getStateCode();
///////////////////////////////////////////////////// default implementation
static class SuspensionStateImpl implements SuspensionState {
public final int stateCode;
protected final String name;
public SuspensionStateImpl(int suspensionCode, String string) {
this.stateCode = suspensionCode;
this.name = string;
}
public int getStateCode() {
return stateCode;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + stateCode;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SuspensionStateImpl other = (SuspensionStateImpl) obj;
if (stateCode != other.stateCode)
return false;
return true;
}
@Override
public String toString() {
return name;
}
}
/////////////////////////////////////////// helper class
public static class SuspensionStateUtil{
public static void setSuspensionState(ProcessDefinitionEntity processDefinitionEntity, SuspensionState state) {
if(processDefinitionEntity.getSuspensionState() == state.getStateCode()) {
throw new ActivitiException("Cannot set suspension state '"+state+"' for "+processDefinitionEntity+"': already in state '"+state+"'.");
}
processDefinitionEntity.setSuspensionState(state.getStateCode());
}
public static void setSuspensionState(ExecutionEntity executionEntity, SuspensionState state) {
if(executionEntity.getSuspensionState() == state.getStateCode()) {
throw new ActivitiException("Cannot set suspension state '"+state+"' for "+executionEntity+"': already in state '"+state+"'.");
}
executionEntity.setSuspensionState(state.getStateCode());
}
}
}
......@@ -29,6 +29,7 @@ import org.activiti.engine.runtime.ProcessInstance;
*
* @author Tom Baeyens
* @author Joram Barez
* @author Daniel Meyer
*/
public interface ProcessDefinition {
......@@ -59,4 +60,7 @@ public interface ProcessDefinition {
/** Does this process definition has a {@link FormService#getStartFormData(String) start form key}. */
boolean hasStartFormKey();
/** Returns trure if the process definition is in state suspended */
boolean isSuspended();
}
......@@ -21,6 +21,7 @@ import org.activiti.engine.query.Query;
*
* @author Tom Baeyens
* @author Joram Barrez
* @author Daniel Meyer
*/
public interface ProcessDefinitionQuery extends Query<ProcessDefinitionQuery, ProcessDefinition> {
......@@ -86,6 +87,16 @@ public interface ProcessDefinitionQuery extends Query<ProcessDefinitionQuery, Pr
/** Only select process definition with a resource name like the given . */
ProcessDefinitionQuery processDefinitionResourceNameLike(String resourceNameLike);
/**
* Only selects process definitions which are suspended
*/
ProcessDefinitionQuery suspended();
/**
* Only selects process definitions which are active
*/
ProcessDefinitionQuery active();
// ordering ////////////////////////////////////////////////////////////
......
......@@ -20,6 +20,7 @@ import org.activiti.engine.repository.ProcessDefinition;
*
* @author Tom Baeyens
* @author Joram Barrez
* @author Daniel Meyer
*/
public interface ProcessInstance extends Execution {
......@@ -33,4 +34,9 @@ public interface ProcessInstance extends Execution {
*/
String getBusinessKey();
/**
* returns true if the process instance is suspended
*/
boolean isSuspended();
}
......@@ -129,7 +129,20 @@ public interface ProcessInstanceQuery extends Query<ProcessInstanceQuery, Proces
* starts with (string%), ends with (%string) or contains (%string%).
*/
ProcessInstanceQuery variableValueLike(String name, String value);
/**
* Only selects process instances which are suspended, either because the
* process instance itself is suspended or because the corresponding process
* definition is suspended
*/
ProcessInstanceQuery suspended();
/**
* Only selects process instances which are active, which means that
* neither the process instance nor the corresponding process definition
* are suspended.
*/
ProcessInstanceQuery active();
//ordering /////////////////////////////////////////////////////////////////
......
......@@ -44,6 +44,7 @@ create table ACT_RU_EXECUTION (
IS_SCOPE_ smallint check(IS_SCOPE_ in (1,0)),
UNI_BUSINESS_KEY varchar (255) not null generated always as (case when "BUSINESS_KEY_" is null then "ID_" else "BUSINESS_KEY_" end),
UNI_PROC_DEF_ID varchar (64) not null generated always as (case when "PROC_DEF_ID_" is null then "ID_" else "PROC_DEF_ID_" end),
SUSPENSION_STATE_ integer,
primary key (ID_)
);
......@@ -68,6 +69,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ varchar(64) not null,
REV_ integer,
CATEGORY_ varchar(255),
NAME_ varchar(255),
KEY_ varchar(255),
......@@ -76,6 +78,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ varchar(4000),
DGRM_RESOURCE_NAME_ varchar(4000),
HAS_START_FORM_KEY_ smallint check(HAS_START_FORM_KEY_ in (1,0)),
SUSPENSION_STATE_ integer,
primary key (ID_)
);
......
......@@ -42,6 +42,7 @@ create table ACT_RU_EXECUTION (
IS_ACTIVE_ bit,
IS_CONCURRENT_ bit,
IS_SCOPE_ bit,
SUSPENSION_STATE_ integer,
primary key (ID_)
);
......@@ -66,6 +67,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ varchar(64),
REV_ integer,
CATEGORY_ varchar(255),
NAME_ varchar(255),
KEY_ varchar(255),
......@@ -74,6 +76,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ varchar(4000),
DGRM_RESOURCE_NAME_ varchar(4000),
HAS_START_FORM_KEY_ bit,
SUSPENSION_STATE_ integer,
primary key (ID_)
);
......
......@@ -42,6 +42,7 @@ create table ACT_RU_EXECUTION (
IS_ACTIVE_ tinyint,
IS_CONCURRENT_ tinyint,
IS_SCOPE_ tinyint,
SUSPENSION_STATE_ tinyint,
primary key (ID_)
);
......@@ -66,6 +67,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ nvarchar(64),
REV_ int,
CATEGORY_ nvarchar(255),
NAME_ nvarchar(255),
KEY_ nvarchar(255),
......@@ -74,6 +76,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ nvarchar(4000),
DGRM_RESOURCE_NAME_ nvarchar(4000),
HAS_START_FORM_KEY_ tinyint,
SUSPENSION_STATE_ tinyint,
primary key (ID_)
);
......
......@@ -42,6 +42,7 @@ create table ACT_RU_EXECUTION (
IS_ACTIVE_ TINYINT,
IS_CONCURRENT_ TINYINT,
IS_SCOPE_ TINYINT,
SUSPENSION_STATE_ integer,
primary key (ID_),
unique ACT_UNIQ_RU_BUS_KEY (PROC_DEF_ID_, BUSINESS_KEY_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
......@@ -67,6 +68,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ varchar(64),
REV_ integer,
CATEGORY_ varchar(255),
NAME_ varchar(255),
KEY_ varchar(255),
......@@ -75,6 +77,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ varchar(4000),
DGRM_RESOURCE_NAME_ varchar(4000),
HAS_START_FORM_KEY_ TINYINT,
SUSPENSION_STATE_ integer,
primary key (ID_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
......
......@@ -42,6 +42,7 @@ create table ACT_RU_EXECUTION (
IS_ACTIVE_ NUMBER(1,0) CHECK (IS_ACTIVE_ IN (1,0)),
IS_CONCURRENT_ NUMBER(1,0) CHECK (IS_CONCURRENT_ IN (1,0)),
IS_SCOPE_ NUMBER(1,0) CHECK (IS_SCOPE_ IN (1,0)),
SUSPENSION_STATE_ INTEGER,
primary key (ID_)
);
......@@ -66,6 +67,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ NVARCHAR2(64),
REV_ INTEGER,
CATEGORY_ NVARCHAR2(255),
NAME_ NVARCHAR2(255),
KEY_ NVARCHAR2(255),
......@@ -74,6 +76,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ NVARCHAR2(2000),
DGRM_RESOURCE_NAME_ varchar(4000),
HAS_START_FORM_KEY_ NUMBER(1,0) CHECK (HAS_START_FORM_KEY_ IN (1,0)),
SUSPENSION_STATE_ INTEGER,
primary key (ID_)
);
......
......@@ -42,6 +42,7 @@ create table ACT_RU_EXECUTION (
IS_ACTIVE_ boolean,
IS_CONCURRENT_ boolean,
IS_SCOPE_ boolean,
SUSPENSION_STATE_ integer,
primary key (ID_),
unique (PROC_DEF_ID_, BUSINESS_KEY_)
);
......@@ -67,6 +68,7 @@ create table ACT_RU_JOB (
create table ACT_RE_PROCDEF (
ID_ varchar(64),
REV_ integer,
CATEGORY_ varchar(255),
NAME_ varchar(255),
KEY_ varchar(255),
......@@ -75,6 +77,7 @@ create table ACT_RE_PROCDEF (
RESOURCE_NAME_ varchar(4000),
DGRM_RESOURCE_NAME_ varchar(4000),
HAS_START_FORM_KEY_ boolean,
SUSPENSION_STATE_ integer,
primary key (ID_)
);
......
......@@ -7,7 +7,7 @@
<!-- EXECUTION INSERT -->
<insert id="insertExecution" parameterType="org.activiti.engine.impl.persistence.entity.ExecutionEntity">
insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, PARENT_ID_, SUPER_EXEC_)
insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUSPENSION_STATE_)
values (
#{id ,jdbcType=VARCHAR},
1,
......@@ -19,7 +19,8 @@
#{isConcurrent ,jdbcType=BOOLEAN},
#{isScope ,jdbcType=BOOLEAN},
#{parentId, jdbcType=VARCHAR},
#{superExecutionId, jdbcType=VARCHAR}
#{superExecutionId, jdbcType=VARCHAR},
#{suspensionState, jdbcType=INTEGER}
)
</insert>
......@@ -34,7 +35,8 @@
IS_CONCURRENT_ = #{isConcurrent, jdbcType=BOOLEAN},
IS_SCOPE_ = #{isScope, jdbcType=BOOLEAN},
PARENT_ID_ = #{parentId, jdbcType=VARCHAR},
SUPER_EXEC_ = #{superExecutionId, jdbcType=VARCHAR}
SUPER_EXEC_ = #{superExecutionId, jdbcType=VARCHAR},
SUSPENSION_STATE_ = #{suspensionState, jdbcType=INTEGER}
where ID_ = #{id, jdbcType=VARCHAR}
and REV_ = #{revision, jdbcType=INTEGER}
</update>
......@@ -59,6 +61,7 @@
<result property="isScope" column="IS_SCOPE_" jdbcType="BOOLEAN" />
<result property="parentId" column="PARENT_ID_" jdbcType="VARCHAR" />
<result property="superExecutionId" column="SUPER_EXEC_" jdbcType="VARCHAR" />
<result property="suspensionState" column="SUSPENSION_STATE_" jdbcType="INTEGER"/>
</resultMap>
<!-- EXECUTION SELECT -->
......@@ -147,6 +150,14 @@
<if test="subProcessInstanceId != null">
and E.ID_ = (select PROC_INST_ID_ from ACT_RU_EXECUTION where ID_ = (select SUPER_EXEC_ from ACT_RU_EXECUTION where ID_ = #{subProcessInstanceId}))
</if>
<if test="suspensionState != null">
<if test="suspensionState.stateCode == 1">
and ((E.SUSPENSION_STATE_ = 1) and (P.SUSPENSION_STATE_ = 1))
</if>
<if test="suspensionState.stateCode == 2">
and ((E.SUSPENSION_STATE_ = 2) or (P.SUSPENSION_STATE_ = 2))
</if>
</if>
<foreach collection="queryVariableValues" index="index" item="queryVariableValue">
and A${index}.NAME_= #{queryVariableValue.name}
<if test="!queryVariableValue.type.equals('null')">
......
......@@ -48,34 +48,42 @@
</select>
<select id="selectNextJobsToExecute" parameterType="string" resultMap="jobResultMap">
select *
from ACT_RU_JOB
where (RETRIES_ &gt; 0)
and (DUEDATE_ is null or DUEDATE_ &lt; #{now, jdbcType=TIMESTAMP})
and (LOCK_OWNER_ is null or LOCK_EXP_TIME_ &lt; #{now, jdbcType=TIMESTAMP})
and (RETRIES_ &gt; 0)
select
JOB.*
from ACT_RU_JOB JOB
LEFT OUTER JOIN ACT_RU_EXECUTION PI ON PI.ID_ = JOB.PROCESS_INSTANCE_ID_
LEFT OUTER JOIN ACT_RE_PROCDEF PD ON PD.ID_ = PI.PROC_DEF_ID_
where (JOB.RETRIES_ &gt; 0)
and (JOB.DUEDATE_ is null or JOB.DUEDATE_ &lt; #{now, jdbcType=TIMESTAMP})
and (JOB.LOCK_OWNER_ is null or JOB.LOCK_EXP_TIME_ &lt; #{now, jdbcType=TIMESTAMP})
and (JOB.RETRIES_ &gt; 0)
and (
(JOB.EXECUTION_ID_ is null)
or ((PI.SUSPENSION_STATE_ = 1)
and (PD.SUSPENSION_STATE_ = 1))
)
</select>
<select id="selectExclusiveJobsToExecute" parameterType="map" resultMap="jobResultMap">
select *
from ACT_RU_JOB
from ACT_RU_JOB
where (RETRIES_ &gt; 0)
and (DUEDATE_ is null or DUEDATE_ &lt; #{now, jdbcType=TIMESTAMP})
and (LOCK_OWNER_ is null or LOCK_EXP_TIME_ &lt; #{now, jdbcType=TIMESTAMP})
and (RETRIES_ &gt; 0)
and (EXCLUSIVE_ = TRUE)
and (PROCESS_INSTANCE_ID_ = #{pid})
and (PROCESS_INSTANCE_ID_ = #{pid})
</select>
<select id="selectExclusiveJobsToExecute_oracle" parameterType="map" resultMap="jobResultMap">
select *
from ACT_RU_JOB
from ACT_RU_JOB
where (RETRIES_ &gt; 0)
and (DUEDATE_ is null or DUEDATE_ &lt; #{now, jdbcType=TIMESTAMP})
and (LOCK_OWNER_ is null or LOCK_EXP_TIME_ &lt; #{now, jdbcType=TIMESTAMP})
and (RETRIES_ &gt; 0)
and (EXCLUSIVE_ = 1)
and (PROCESS_INSTANCE_ID_ = #{pid})
and (PROCESS_INSTANCE_ID_ = #{pid})
</select>
<select id="selectLockedJobs" resultMap="jobResultMap">
......@@ -152,11 +160,18 @@
<!-- SELECT DEPENDENT -->
<select id="selectNextJobsToExecute_mysql" parameterType="string" resultMap="jobResultMap">
select *
from ACT_RU_JOB
select JOB.*
from ACT_RU_JOB JOB
LEFT OUTER JOIN ACT_RU_EXECUTION PI ON PI.ID_ = JOB.PROCESS_INSTANCE_ID_
LEFT OUTER JOIN ACT_RE_PROCDEF PD ON PD.ID_ = PI.PROC_DEF_ID_
where (RETRIES_ &gt; 0)
and (DUEDATE_ is null or DUEDATE_ &lt;= #{now, jdbcType=TIMESTAMP})
and (LOCK_OWNER_ is null or LOCK_EXP_TIME_ &lt;= #{now, jdbcType=TIMESTAMP})
and (
(JOB.EXECUTION_ID_ is null)
or ((PI.SUSPENSION_STATE_ = 1)
and (PD.SUSPENSION_STATE_ = 1))
)
</select>
<select id="selectExclusiveJobsToExecute_mysql" parameterType="map" resultMap="jobResultMap">
......
......@@ -7,8 +7,9 @@
<!-- PROCESSDEFINITION INSERT -->
<insert id="insertProcessDefinition" parameterType="org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity">
insert into ACT_RE_PROCDEF(ID_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, HAS_START_FORM_KEY_)
insert into ACT_RE_PROCDEF(ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, HAS_START_FORM_KEY_, SUSPENSION_STATE_)
values (#{id, jdbcType=VARCHAR},
1,
#{category, jdbcType=VARCHAR},
#{name, jdbcType=VARCHAR},
#{key, jdbcType=VARCHAR},
......@@ -16,11 +17,20 @@
#{deploymentId, jdbcType=VARCHAR},
#{resourceName, jdbcType=VARCHAR},
#{diagramResourceName, jdbcType=VARCHAR},
#{hasStartFormKey, jdbcType=BOOLEAN})
#{hasStartFormKey, jdbcType=BOOLEAN},
#{suspensionState, jdbcType=INTEGER})
</insert>
<!-- PROCESSDEFINITION UPDATE -->
<update id="updateProcessDefinition" parameterType="org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity">
update ACT_RE_PROCDEF set
REV_ = #{revisionNext, jdbcType=INTEGER},
SUSPENSION_STATE_ = #{suspensionState, jdbcType=INTEGER}
where ID_ = #{id, jdbcType=VARCHAR}
and REV_ = #{revision, jdbcType=INTEGER}
</update>
<!-- PROCESSDEFINITION DELETE -->
<delete id="deleteProcessDefinitionsByDeploymentId" parameterType="string">
......@@ -31,6 +41,7 @@
<resultMap id="processDefinitionResultMap" type="org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity">
<id property="id" column="ID_" jdbcType="VARCHAR" />
<result property="revision" column="REV_" />
<result property="category" column="CATEGORY_" />
<result property="name" column="NAME_" />
<result property="key" column="KEY_" jdbcType="VARCHAR" />
......@@ -39,6 +50,7 @@
<result property="resourceName" column="RESOURCE_NAME_" jdbcType="VARCHAR"/>
<result property="diagramResourceName" column="DGRM_RESOURCE_NAME_" jdbcType="VARCHAR"/>
<result property="hasStartFormKey" column="HAS_START_FORM_KEY_" jdbcType="BOOLEAN"/>
<result property="suspensionState" column="SUSPENSION_STATE_" jdbcType="INTEGER"/>
</resultMap>
<!-- PROCESSDEFINITION SELECT -->
......@@ -96,6 +108,9 @@
<if test="latest">
and PD.VERSION_ = (select max(VERSION_) from ACT_RE_PROCDEF where KEY_ = PD.KEY_)
</if>
<if test="suspensionState != null">
and (PD.SUSPENSION_STATE_ = #{suspensionState.stateCode})
</if>
</where>
</sql>
......
alter table AT_RU_EXECUTION
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add REV_ integer;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
alter table AT_RU_EXECUTION
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add REV_ integer;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
alter table AT_RU_EXECUTION
add SUSPENSION_STATE_ int;
alter table ACT_RE_PROCDEF
add SUSPENSION_STATE_ int;
alter table ACT_RE_PROCDEF
add REV_ int;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
alter table AT_RU_EXECUTION
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add REV_ integer;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
alter table AT_RU_EXECUTION
add SUSPENSION_STATE_ INTEGER;
alter table ACT_RE_PROCDEF
add SUSPENSION_STATE_ INTEGER;
alter table ACT_RE_PROCDEF
add REV_ INTEGER;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
alter table AT_RU_EXECUTION
add column SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add column SUSPENSION_STATE_ integer;
alter table ACT_RE_PROCDEF
add column REV_ integer;
update ACT_RE_PROCDEF set REV_ = 1;
update ACT_RE_PROCDEF set SUSPENSION_STATE_ = 1;
update AT_RU_EXECUTION set SUSPENSION_STATE_ = 1;
package org.activiti.engine.test.api.repository;
import java.util.List;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.test.Deployment;
/**
*
* @author Daniel Meyer
*/
public class ProcessDefinitionSuspensionTest extends PluggableActivitiTestCase {
@Deployment(resources={"org/activiti/engine/test/db/processOne.bpmn20.xml"})
public void testProcessDefinitionActiveByDefault() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
}
@Deployment(resources={"org/activiti/engine/test/db/processOne.bpmn20.xml"})
public void testSuspendActivateProcessDefinitionById() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
// suspend
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertTrue(processDefinition.isSuspended());
// activate
repositoryService.activateProcessDefinitionById(processDefinition.getId());
processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
}
@Deployment(resources={"org/activiti/engine/test/db/processOne.bpmn20.xml"})
public void testSuspendActivateProcessDefinitionByKey() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
//suspend
repositoryService.suspendProcessDefinitionByKey(processDefinition.getKey());
processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertTrue(processDefinition.isSuspended());
//activate
repositoryService.activateProcessDefinitionByKey(processDefinition.getKey());
processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
}
@Deployment(resources={"org/activiti/engine/test/db/processOne.bpmn20.xml"})
public void testCannotActivateActiveProcessDefinition() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
try {
repositoryService.activateProcessDefinitionById(processDefinition.getId());
fail("Exception exprected");
}catch (ActivitiException e) {
// expected
}
}
@Deployment(resources={"org/activiti/engine/test/db/processOne.bpmn20.xml"})
public void testCannotSuspendActiveProcessDefinition() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertFalse(processDefinition.isSuspended());
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
try {
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
fail("Exception exprected");
}catch (ActivitiException e) {
// expected
}
}
@Deployment(resources={
"org/activiti/engine/test/db/processOne.bpmn20.xml",
"org/activiti/engine/test/db/processTwo.bpmn20.xml"
})
public void testQueryForActiveDefinitions() {
// default = all definitions
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
.list();
assertEquals(2, processDefinitionList.size());
assertEquals(2, repositoryService.createProcessDefinitionQuery().active().count());
ProcessDefinition processDefinition = processDefinitionList.get(0);
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
assertEquals(2, repositoryService.createProcessDefinitionQuery().count());
assertEquals(1, repositoryService.createProcessDefinitionQuery().active().count());
}
@Deployment(resources={
"org/activiti/engine/test/db/processOne.bpmn20.xml",
"org/activiti/engine/test/db/processTwo.bpmn20.xml"
})
public void testQueryForSuspendedDefinitions() {
// default = all definitions
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
.list();
assertEquals(2, processDefinitionList.size());
assertEquals(2, repositoryService.createProcessDefinitionQuery().active().count());
ProcessDefinition processDefinition = processDefinitionList.get(0);
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
assertEquals(2, repositoryService.createProcessDefinitionQuery().count());
assertEquals(1, repositoryService.createProcessDefinitionQuery().suspended().count());
}
}
package org.activiti.engine.test.api.runtime;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.Deployment;
/**
*
* @author Daniel Meyer
*/
public class ProcessInstanceSuspensionTest extends PluggableActivitiTestCase {
@Deployment(resources={"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testProcessInstanceActiveByDefault() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
runtimeService.startProcessInstanceByKey(processDefinition.getKey());
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertFalse(processInstance.isSuspended());
}
@Deployment(resources={"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testSuspendActivateProcessInstance() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
runtimeService.startProcessInstanceByKey(processDefinition.getKey());
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertFalse(processInstance.isSuspended());
//suspend
runtimeService.suspendProcessInstanceById(processInstance.getId());
processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertTrue(processInstance.isSuspended());
//activate
runtimeService.activateProcessInstanceById(processInstance.getId());
processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertFalse(processInstance.isSuspended());
}
@Deployment(resources={"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testCannotActivateActiveProcessInstance() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
runtimeService.startProcessInstanceByKey(processDefinition.getKey());
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertFalse(processInstance.isSuspended());
try {
//activate
runtimeService.activateProcessInstanceById(processInstance.getId());
fail("Expected activiti exception");
}catch (ActivitiException e) {
// expected
}
}
@Deployment(resources={"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testCannotSuspendSuspendedProcessInstance() {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
runtimeService.startProcessInstanceByKey(processDefinition.getKey());
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().singleResult();
assertFalse(processInstance.isSuspended());
runtimeService.suspendProcessInstanceById(processInstance.getId());
try {
runtimeService.suspendProcessInstanceById(processInstance.getId());
fail("Expected activiti exception");
}catch (ActivitiException e) {
// expected
}
}
@Deployment(resources={
"org/activiti/engine/test/api/runtime/superProcessWithMultipleNestedSubProcess.bpmn20.xml",
"org/activiti/engine/test/api/runtime/nestedSubProcess.bpmn20.xml",
"org/activiti/engine/test/api/runtime/subProcess.bpmn20.xml"
})
public void testQueryForActiveAndSuspendedProcessInstances() {
runtimeService.startProcessInstanceByKey("nestedSubProcessQueryTest");
assertEquals(5, runtimeService.createProcessInstanceQuery().count());
assertEquals(5, runtimeService.createProcessInstanceQuery().active().count());
assertEquals(0, runtimeService.createProcessInstanceQuery().suspended().count());
ProcessInstance piToSuspend = runtimeService.createProcessInstanceQuery()
.processDefinitionKey("nestedSubProcessQueryTest")
.singleResult();
runtimeService.suspendProcessInstanceById(piToSuspend.getId());
assertEquals(5, runtimeService.createProcessInstanceQuery().count());
assertEquals(4, runtimeService.createProcessInstanceQuery().active().count());
assertEquals(1, runtimeService.createProcessInstanceQuery().suspended().count());
assertEquals(piToSuspend.getId(), runtimeService.createProcessInstanceQuery().suspended().singleResult().getId());
}
}
package org.activiti.engine.test.db;
import org.activiti.engine.impl.cmd.AcquireJobsCmd;
import org.activiti.engine.impl.jobexecutor.AcquiredJobs;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.Deployment;
/**
*
* @author Daniel Meyer
*/
public class ProcessInstanceSuspensionTest extends PluggableActivitiTestCase {
@Deployment(resources={"org/activiti/engine/test/db/oneJobProcess.bpmn20.xml"})
public void testJobsNotVisisbleToAcquisitionIfInstanceSuspended() {
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().singleResult();
ProcessInstance pi = runtimeService.startProcessInstanceByKey(pd.getKey());
// now there is one job:
assertNotNull(managementService.createJobQuery()
.singleResult());
// the acquirejobs command sees the job:
AcquiredJobs acquiredJobs = executeAcquireJobsCommand();
assertEquals(1, acquiredJobs.size());
// suspend the process instance:
runtimeService.suspendProcessInstanceById(pi.getId());
// now, the acquirejobs command does not see the job:
acquiredJobs = executeAcquireJobsCommand();
assertEquals(0, acquiredJobs.size());
}
@Deployment(resources={"org/activiti/engine/test/db/oneJobProcess.bpmn20.xml"})
public void testJobsNotVisisbleToAcquisitionIfDefinitionSuspended() {
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().singleResult();
runtimeService.startProcessInstanceByKey(pd.getKey());
// now there is one job:
assertNotNull(managementService.createJobQuery()
.singleResult());
// the acquirejobs command sees the job:
AcquiredJobs acquiredJobs = executeAcquireJobsCommand();
assertEquals(1, acquiredJobs.size());
// suspend the process instance:
repositoryService.suspendProcessDefinitionById(pd.getId());
// now, the acquirejobs command does not see the job:
acquiredJobs = executeAcquireJobsCommand();
assertEquals(0, acquiredJobs.size());
}
private AcquiredJobs executeAcquireJobsCommand() {
return processEngineConfiguration.getCommandExecutorTxRequired()
.execute(new AcquireJobsCmd(processEngineConfiguration.getJobExecutor()));
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="org.activiti.enginge.test.api.runtime">
<process id="nestedSubProcessQueryTest">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
<parallelGateway id="fork" />
<sequenceFlow sourceRef="fork" targetRef="callSubProcess1" />
<sequenceFlow sourceRef="fork" targetRef="callSubProcess2" />
<callActivity id="callSubProcess1" calledElement="nestedSimpleSubProcess" />
<callActivity id="callSubProcess2" calledElement="nestedSimpleSubProcess" />
<sequenceFlow sourceRef="callSubProcess1" targetRef="join" />
<sequenceFlow sourceRef="callSubProcess2" targetRef="join" />
<parallelGateway id="join" />
<sequenceFlow id="flow3" sourceRef="join" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="org.activiti.enginge.test.api.runtime">
<process id="oneTaskProcess" name="oneTaskProcess">
<startEvent id="theStart" name="Start"></startEvent>
<endEvent id="theEnd" name="End"></endEvent>
<intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent">
<timerEventDefinition>
<timeDuration>PT0S</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>
<sequenceFlow id="flow1" name="" sourceRef="theStart" targetRef="timerintermediatecatchevent1"></sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="timerintermediatecatchevent1" targetRef="theEnd"></sequenceFlow>
</process>
</definitions>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册