/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* 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.jbpm.casemgmt.impl.command;
import org.jbpm.casemgmt.api.CaseNotFoundException;
import org.jbpm.casemgmt.impl.event.CaseEventSupport;
import org.jbpm.runtime.manager.impl.PerCaseRuntimeManager;
import org.jbpm.services.api.ProcessService;
import org.jbpm.services.api.RuntimeDataService;
import org.jbpm.services.api.model.ProcessInstanceDesc;
import org.kie.api.runtime.Context;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.runtime.query.QueryContext;
import org.kie.internal.KieInternalServices;
import org.kie.internal.identity.IdentityProvider;
import org.kie.internal.process.CorrelationKey;
import org.kie.internal.process.CorrelationKeyFactory;
import org.kie.internal.runtime.manager.context.CaseContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.List;
import static java.util.stream.Collectors.toList;
public class CancelCaseCommand extends CaseCommand<Void> {
private static final long serialVersionUID = 6811181095390934149L;
private static final Logger logger = LoggerFactory.getLogger(CancelCaseCommand.class);
private static CorrelationKeyFactory correlationKeyFactory = KieInternalServices.Factory.get().newCorrelationKeyFactory();
private String caseId;
private transient ProcessService processService;
private transient RuntimeDataService runtimeDataService;
private boolean destroy;
public CancelCaseCommand(IdentityProvider identityProvider, String caseId, ProcessService processService, RuntimeDataService runtimeDataService, boolean destroy) {
super(identityProvider);
this.caseId = caseId;
this.processService = processService;
this.runtimeDataService = runtimeDataService;
this.destroy = destroy;
}
@Override
public Void execute(Context context) {
CorrelationKey correlationKey = correlationKeyFactory.newCorrelationKey(caseId);
Collection<ProcessInstanceDesc> caseProcesses = runtimeDataService.getProcessInstancesByCorrelationKey(correlationKey, new QueryContext(0, 1000));
if (caseProcesses.isEmpty()) {
throw new CaseNotFoundException("Case with id " + caseId + " was not found");
}
List<Long> processInstanceIds = caseProcesses.stream()
.filter(pi -> pi.getState().equals(ProcessInstance.STATE_ACTIVE))
.sorted((ProcessInstanceDesc o1, ProcessInstanceDesc o2) -> {
return Long.valueOf(o2.getParentId()).compareTo(Long.valueOf(o1.getParentId()));
}
)
.map(pi -> pi.getId()).collect(toList());
CaseEventSupport caseEventSupport = getCaseEventSupport(context);
caseEventSupport.fireBeforeCaseCancelled(caseId, processInstanceIds);
logger.debug("Case {} consists of following process instances (ids) {}", caseId, processInstanceIds);
processService.abortProcessInstances(processInstanceIds);
caseEventSupport.fireAfterCaseCancelled(caseId, processInstanceIds);
if (destroy) {
RuntimeManager runtimeManager = getRuntimeManager(context);
if (runtimeManager instanceof PerCaseRuntimeManager) {
caseEventSupport.fireBeforeCaseDestroyed(caseId, processInstanceIds);
logger.debug("Case {} aborted, destroying case data including per case runtime engine (including working memory)", caseId);
((PerCaseRuntimeManager) runtimeManager).destroyCase(CaseContext.get(caseId));
caseEventSupport.fireAfterCaseDestroyed(caseId, processInstanceIds);
}
}
return null;
}
public void setProcessService(ProcessService processService) {
this.processService = processService;
}
}