org.bonitasoft.engine.api.impl.resolver.BusinessArchiveArtifactsManager Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2019 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.bonitasoft.engine.api.impl.resolver;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.bonitasoft.engine.bpm.bar.BusinessArchive;
import org.bonitasoft.engine.bpm.bar.BusinessArchiveBuilder;
import org.bonitasoft.engine.bpm.bar.InvalidBusinessArchiveFormatException;
import org.bonitasoft.engine.bpm.process.ConfigurationState;
import org.bonitasoft.engine.bpm.process.DesignProcessDefinition;
import org.bonitasoft.engine.bpm.process.Problem;
import org.bonitasoft.engine.builder.BuilderFactory;
import org.bonitasoft.engine.commons.exceptions.SBonitaException;
import org.bonitasoft.engine.commons.exceptions.SObjectModificationException;
import org.bonitasoft.engine.core.process.definition.ProcessDefinitionService;
import org.bonitasoft.engine.core.process.definition.model.SProcessDefinition;
import org.bonitasoft.engine.core.process.definition.model.SProcessDefinitionDeployInfo;
import org.bonitasoft.engine.core.process.definition.model.builder.SProcessDefinitionDeployInfoUpdateBuilderFactory;
import org.bonitasoft.engine.exception.BonitaException;
import org.bonitasoft.engine.persistence.SBonitaReadException;
import org.bonitasoft.engine.recorder.SRecorderException;
import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor;
import org.bonitasoft.engine.service.ServiceAccessor;
/**
* Handles the resolution of Process Dependencies. A process can have a list of ProcessDependencyResolver
s
* which validates different aspects of the
* process to validate (or "resolve")
*
* @author Emmanuel Duchastenier
* @author Matthieu Chaffotte
* @author Celine Souchet
*/
@Slf4j
public class BusinessArchiveArtifactsManager {
private final List dependencyResolvers;
public BusinessArchiveArtifactsManager(final List dependencyResolvers) {
this.dependencyResolvers = dependencyResolvers;
}
public boolean resolveDependencies(final BusinessArchive businessArchive, final SProcessDefinition sDefinition) {
final List artifactManagers = getArtifactManagers();
boolean resolved = true;
for (final BusinessArchiveArtifactManager artifactManager : artifactManagers) {
try {
resolved &= artifactManager.deploy(businessArchive, sDefinition);
if (!resolved) {
for (Problem problem : artifactManager.checkResolution(sDefinition)) {
log.info(problem.getDescription());
}
}
} catch (BonitaException | SBonitaException e) {
// not logged, we will check later why the process is not resolved
log.error("Unable to deploy process", e);
resolved = false;
}
}
return resolved;
}
public void resolveDependenciesForAllProcesses(ServiceAccessor serviceAccessor) {
try {
List processDefinitionIds = serviceAccessor.getProcessDefinitionService().getProcessDefinitionIds(0,
Integer.MAX_VALUE);
resolveDependencies(processDefinitionIds, serviceAccessor);
} catch (SBonitaReadException e) {
log.error("Unable to retrieve tenant process definitions, dependency resolution aborted");
}
}
private void resolveDependencies(final List processDefinitionIds, final ServiceAccessor serviceAccessor) {
for (Long id : processDefinitionIds) {
resolveDependencies(id, serviceAccessor);
}
}
public void deleteDependencies(final SProcessDefinition processDefinition)
throws SObjectModificationException, SBonitaReadException, SRecorderException {
final List resolvers = getArtifactManagers();
for (BusinessArchiveArtifactManager resolver : resolvers) {
resolver.delete(processDefinition);
}
}
/*
* Done in a separated transaction
* We try here to check if now the process is resolved so it must not be done in the same transaction that did the
* modification
* this does not throw exception, it only log because it can be retried after.
*/
public void resolveDependencies(final long processDefinitionId, final ServiceAccessor serviceAccessor) {
resolveDependencies(processDefinitionId, serviceAccessor,
getArtifactManagers().toArray(new BusinessArchiveArtifactManager[0]));
}
public void resolveDependencies(final long processDefinitionId, final ServiceAccessor serviceAccessor,
final BusinessArchiveArtifactManager... resolvers) {
final ProcessDefinitionService processDefinitionService = serviceAccessor.getProcessDefinitionService();
try {
boolean resolved = true;
for (final BusinessArchiveArtifactManager dependencyResolver : resolvers) {
final SProcessDefinition processDefinition = processDefinitionService
.getProcessDefinition(processDefinitionId);
resolved &= dependencyResolver.checkResolution(processDefinition).isEmpty();
}
changeResolutionStatus(processDefinitionId, processDefinitionService, resolved);
} catch (final SBonitaException e) {
if (log.isDebugEnabled()) {
log.debug(e.toString());
}
log.warn("Unable to resolve dependencies after they were modified because of " + e.getMessage()
+ ". Please retry it manually");
}
}
public void changeResolutionStatus(final long processDefinitionId,
final ProcessDefinitionService processDefinitionService,
final boolean resolved) throws SBonitaException {
final SProcessDefinitionDeployInfo processDefinitionDeployInfo = processDefinitionService
.getProcessDeploymentInfo(processDefinitionId);
if (resolved) {
if (ConfigurationState.UNRESOLVED.name().equals(processDefinitionDeployInfo.getConfigurationState())) {
processDefinitionService.resolveProcess(processDefinitionId);
}
} else {
if (ConfigurationState.RESOLVED.name().equals(processDefinitionDeployInfo.getConfigurationState())) {
final EntityUpdateDescriptor updateDescriptor = BuilderFactory
.get(SProcessDefinitionDeployInfoUpdateBuilderFactory.class).createNewInstance()
.updateConfigurationState(ConfigurationState.UNRESOLVED).done();
processDefinitionService.updateProcessDefinitionDeployInfo(processDefinitionId, updateDescriptor);
}
}
}
public List getArtifactManagers() {
return dependencyResolvers;
}
public BusinessArchive exportBusinessArchive(long processDefinitionId,
DesignProcessDefinition designProcessDefinition)
throws InvalidBusinessArchiveFormatException, SBonitaException {
final BusinessArchiveBuilder businessArchiveBuilder = new BusinessArchiveBuilder().createNewBusinessArchive();
businessArchiveBuilder.setProcessDefinition(designProcessDefinition);
for (BusinessArchiveArtifactManager businessArchiveArtifactManager : getArtifactManagers()) {
businessArchiveArtifactManager.exportToBusinessArchive(processDefinitionId, businessArchiveBuilder);
}
return businessArchiveBuilder.done();
}
public List getProcessResolutionProblems(SProcessDefinition processDefinition) {
return getArtifactManagers().stream().flatMap(resolver -> resolver.checkResolution(processDefinition).stream())
.collect(Collectors.toList());
}
}