Skip to content

Commit

Permalink
Add option to set variables async for bpmn and cmmn
Browse files Browse the repository at this point in the history
  • Loading branch information
tijsrademakers committed Oct 16, 2024
1 parent a586e9e commit 5f1f990
Show file tree
Hide file tree
Showing 21 changed files with 1,131 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ public interface CmmnRuntimeService {

void setLocalVariable(String planItemInstanceId, String variableName, Object variableValue);

void setVariablesAsync(String caseInstanceId, Map<String, Object> variables);

void setVariableAsync(String caseInstanceId, String variableName, Object variableValue);

void setLocalVariablesAsync(String planItemInstanceId, Map<String, Object> variables);

void setLocalVariableAsync(String planItemInstanceId, String variableName, Object variableValue);

void removeVariable(String caseInstanceId, String variableName);

void removeVariables(String caseInstanceId, Collection<String> variableNames);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
import org.flowable.cmmn.engine.impl.job.CmmnHistoryCleanupJobHandler;
import org.flowable.cmmn.engine.impl.job.ExternalWorkerTaskCompleteJobHandler;
import org.flowable.cmmn.engine.impl.job.HistoricCaseInstanceMigrationJobHandler;
import org.flowable.cmmn.engine.impl.job.SetAsyncVariablesJobHandler;
import org.flowable.cmmn.engine.impl.job.TriggerTimerEventJobHandler;
import org.flowable.cmmn.engine.impl.listener.CmmnListenerFactory;
import org.flowable.cmmn.engine.impl.listener.CmmnListenerNotificationHelper;
Expand Down Expand Up @@ -1302,6 +1303,7 @@ public void initDependentScopeTypes() {
this.dependentScopeTypes.add(ScopeTypes.CMMN);
this.dependentScopeTypes.add(ScopeTypes.CMMN_VARIABLE_AGGREGATION);
this.dependentScopeTypes.add(ScopeTypes.CMMN_EXTERNAL_WORKER);
this.dependentScopeTypes.add(ScopeTypes.CMMN_ASYNC_VARIABLES);
}

public void initHistoryConfigurationSettings() {
Expand Down Expand Up @@ -1658,6 +1660,7 @@ public void initJobHandlers() {
jobHandlers.put(AsyncActivatePlanItemInstanceJobHandler.TYPE, new AsyncActivatePlanItemInstanceJobHandler());
jobHandlers.put(AsyncLeaveActivePlanItemInstanceJobHandler.TYPE, new AsyncLeaveActivePlanItemInstanceJobHandler());
jobHandlers.put(AsyncInitializePlanModelJobHandler.TYPE, new AsyncInitializePlanModelJobHandler());
jobHandlers.put(SetAsyncVariablesJobHandler.TYPE, new SetAsyncVariablesJobHandler(this));
jobHandlers.put(CmmnHistoryCleanupJobHandler.TYPE, new CmmnHistoryCleanupJobHandler());
jobHandlers.put(ExternalWorkerTaskCompleteJobHandler.TYPE, new ExternalWorkerTaskCompleteJobHandler(this));
addJobHandler(new CaseInstanceMigrationJobHandler());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* 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.flowable.cmmn.engine.impl.cmd;

import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.job.SetAsyncVariablesJobHandler;
import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity;
import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.job.service.JobService;
import org.flowable.job.service.JobServiceConfiguration;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.variable.service.VariableService;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity;

public abstract class AbstractSetVariableAsyncCmd {

protected void addVariable(boolean isLocal, String scopeId, String subScopeId, String varName, Object varValue,
String tenantId, VariableService variableService) {

VariableInstanceEntity variableInstance = variableService.createVariableInstance(varName);
variableInstance.setScopeId(scopeId);
variableInstance.setSubScopeId(subScopeId);
variableInstance.setScopeType(ScopeTypes.CMMN_ASYNC_VARIABLES);
variableInstance.setMetaInfo(String.valueOf(isLocal));

variableService.insertVariableInstanceWithValue(variableInstance, varValue, tenantId);
}

protected void createSetAsyncVariablesJob(CaseInstanceEntity caseInstanceEntity, CmmnEngineConfiguration cmmnEngineConfiguration) {
JobServiceConfiguration jobServiceConfiguration = cmmnEngineConfiguration.getJobServiceConfiguration();
JobService jobService = jobServiceConfiguration.getJobService();

JobEntity job = jobService.createJob();
job.setScopeId(caseInstanceEntity.getId());
job.setScopeDefinitionId(caseInstanceEntity.getCaseDefinitionId());
job.setScopeType(ScopeTypes.CMMN);
job.setJobHandlerType(SetAsyncVariablesJobHandler.TYPE);

// Inherit tenant id (if applicable)
if (caseInstanceEntity.getTenantId() != null) {
job.setTenantId(caseInstanceEntity.getTenantId());
}

jobService.createAsyncJob(job, true);
jobService.scheduleAsyncJob(job);
}

protected void createSetAsyncVariablesJob(PlanItemInstanceEntity planItemInstanceEntity, CmmnEngineConfiguration cmmnEngineConfiguration) {
JobServiceConfiguration jobServiceConfiguration = cmmnEngineConfiguration.getJobServiceConfiguration();
JobService jobService = jobServiceConfiguration.getJobService();

JobEntity job = jobService.createJob();
job.setScopeId(planItemInstanceEntity.getCaseInstanceId());
job.setSubScopeId(planItemInstanceEntity.getId());
job.setScopeDefinitionId(planItemInstanceEntity.getCaseDefinitionId());
job.setScopeType(ScopeTypes.CMMN);
job.setJobHandlerType(SetAsyncVariablesJobHandler.TYPE);

// Inherit tenant id (if applicable)
if (planItemInstanceEntity.getTenantId() != null) {
job.setTenantId(planItemInstanceEntity.getTenantId());
}

jobService.createAsyncJob(job, true);
jobService.scheduleAsyncJob(job);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* 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.flowable.cmmn.engine.impl.cmd;

import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity;
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;

public class SetLocalVariableAsyncCmd extends AbstractSetVariableAsyncCmd implements Command<Void> {

protected String planItemInstanceId;
protected String variableName;
protected Object variableValue;

public SetLocalVariableAsyncCmd(String planItemInstanceId, String variableName, Object variableValue) {
this.planItemInstanceId = planItemInstanceId;
this.variableName = variableName;
this.variableValue = variableValue;
}

@Override
public Void execute(CommandContext commandContext) {
if (planItemInstanceId == null) {
throw new FlowableIllegalArgumentException("planItemInstanceId is null");
}
if (variableName == null) {
throw new FlowableIllegalArgumentException("variable name is null");
}

CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
PlanItemInstanceEntity planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);
if (planItemInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No plan item instance found for id " + planItemInstanceId, PlanItemInstanceEntity.class);
}

addVariable(true, planItemInstanceEntity.getCaseInstanceId(), planItemInstanceEntity.getId(), variableName, variableValue, planItemInstanceEntity.getTenantId(),
cmmnEngineConfiguration.getVariableServiceConfiguration().getVariableService());
createSetAsyncVariablesJob(planItemInstanceEntity, cmmnEngineConfiguration);

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* 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.flowable.cmmn.engine.impl.cmd;

import java.util.Map;

import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity;
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;

public class SetLocalVariablesAsyncCmd extends AbstractSetVariableAsyncCmd implements Command<Void> {

protected String planItemInstanceId;
protected Map<String, Object> variables;

public SetLocalVariablesAsyncCmd(String planItemInstanceId, Map<String, Object> variables) {
this.planItemInstanceId = planItemInstanceId;
this.variables = variables;
}

@Override
public Void execute(CommandContext commandContext) {
if (planItemInstanceId == null) {
throw new FlowableIllegalArgumentException("planItemInstanceId is null");
}
if (variables == null) {
throw new FlowableIllegalArgumentException("variables is null");
}
if (variables.isEmpty()) {
throw new FlowableIllegalArgumentException("variables is empty");
}

CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
PlanItemInstanceEntity planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);
if (planItemInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No plan item instance found for id " + planItemInstanceId, PlanItemInstanceEntity.class);
}

for (String variableName : variables.keySet()) {
addVariable(true, planItemInstanceEntity.getCaseInstanceId(), planItemInstanceEntity.getId(), variableName, variables.get(variableName),
planItemInstanceEntity.getTenantId(), cmmnEngineConfiguration.getVariableServiceConfiguration().getVariableService());
}

createSetAsyncVariablesJob(planItemInstanceEntity, cmmnEngineConfiguration);

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* 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.flowable.cmmn.engine.impl.cmd;

import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity;
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;

public class SetVariableAsyncCmd extends AbstractSetVariableAsyncCmd implements Command<Void> {

protected String caseInstanceId;
protected String variableName;
protected Object variableValue;

public SetVariableAsyncCmd(String caseInstanceId, String variableName, Object variableValue) {
this.caseInstanceId = caseInstanceId;
this.variableName = variableName;
this.variableValue = variableValue;
}

@Override
public Void execute(CommandContext commandContext) {
if (caseInstanceId == null) {
throw new FlowableIllegalArgumentException("caseInstanceId is null");
}
if (variableName == null) {
throw new FlowableIllegalArgumentException("variable name is null");
}

CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
CaseInstanceEntity caseInstanceEntity = cmmnEngineConfiguration.getCaseInstanceEntityManager().findById(caseInstanceId);
if (caseInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No case instance found for id " + caseInstanceId, CaseInstanceEntity.class);
}

addVariable(false, caseInstanceId, null, variableName, variableValue, caseInstanceEntity.getTenantId(),
cmmnEngineConfiguration.getVariableServiceConfiguration().getVariableService());
createSetAsyncVariablesJob(caseInstanceEntity, cmmnEngineConfiguration);

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* 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.flowable.cmmn.engine.impl.cmd;

import java.util.Map;

import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity;
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;

public class SetVariablesAsyncCmd extends AbstractSetVariableAsyncCmd implements Command<Void> {

protected String caseInstanceId;
protected Map<String, Object> variables;

public SetVariablesAsyncCmd(String caseInstanceId, Map<String, Object> variables) {
this.caseInstanceId = caseInstanceId;
this.variables = variables;
}

@Override
public Void execute(CommandContext commandContext) {
if (caseInstanceId == null) {
throw new FlowableIllegalArgumentException("caseInstanceId is null");
}
if (variables == null) {
throw new FlowableIllegalArgumentException("variables is null");
}
if (variables.isEmpty()) {
throw new FlowableIllegalArgumentException("variables is empty");
}

CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
CaseInstanceEntity caseInstanceEntity = cmmnEngineConfiguration.getCaseInstanceEntityManager().findById(caseInstanceId);
if (caseInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No case instance found for id " + caseInstanceId, CaseInstanceEntity.class);
}

for (String variableName : variables.keySet()) {
addVariable(false, caseInstanceId, null, variableName, variables.get(variableName), caseInstanceEntity.getTenantId(),
cmmnEngineConfiguration.getVariableServiceConfiguration().getVariableService());
}

createSetAsyncVariablesJob(caseInstanceEntity, cmmnEngineConfiguration);

return null;
}

}
Loading

0 comments on commit 5f1f990

Please sign in to comment.