All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xlrit.gears.server.graphql.ProcessResolver Maven / Gradle / Ivy

There is a newer version: 1.17.6
Show newest version
package com.xlrit.gears.server.graphql;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.xlrit.gears.base.exception.NotFoundException;
import com.xlrit.gears.base.util.Range;
import com.xlrit.gears.engine.error.InputException;
import com.xlrit.gears.engine.facade.EngineFacade;
import com.xlrit.gears.engine.security.AuthManager;
import lombok.RequiredArgsConstructor;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;

import static com.xlrit.gears.engine.util.EngineUtils.requireFound;

@Controller
@RequiredArgsConstructor
public class ProcessResolver {
	private static final Logger LOG = LoggerFactory.getLogger(ProcessResolver.class);

	private final RepositoryService repositoryService;
	private final RuntimeService    runtimeService;
	private final EngineFacade      engineFacade;
	private final AuthManager       authManager;

	// === process definition queries === //

	@QueryMapping
	@PreAuthorize("isAuthenticated()")
	public List processDefinitions() {
		Set roleNames = authManager.getCurrentUserRoleNames();
		if (roleNames == null || roleNames.isEmpty()) return Collections.emptyList();

		return repositoryService
			.createProcessDefinitionQuery()
			.startableByUserOrGroups(null, roleNames)
			.active()
			.latestVersion()
			.list();
	}

	@QueryMapping
	@PreAuthorize("isAuthenticated()")
	public ProcessDefinition processDefinition(@Argument String id) {
		Set roleNames = authManager.getCurrentUserRoleNames();
		return repositoryService
			.createProcessDefinitionQuery()
			.processDefinitionId(id)
			.startableByUserOrGroups(null, roleNames)
			.singleResult();
	}

	@QueryMapping
	@PreAuthorize("isAuthenticated()")
	public ProcessDefinition processDefinitionByKey(@Argument String key) {
		Set roleNames = authManager.getCurrentUserRoleNames();
		return repositoryService
			.createProcessDefinitionQuery()
			.processDefinitionKey(key)
			.startableByUserOrGroups(null, roleNames)
			.latestVersion()
			.singleResult();
	}

	// === process instance queries === //

	@QueryMapping
	@PreAuthorize("hasRole('admin')")
	public List allActiveProcessInstances(@Argument String filter, @Argument Range range) {
		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
			.orderByStartTime().desc();

		return list(query, range, filter);
	}

	@QueryMapping
	public long allActiveProcessInstancesCount(@Argument String filter) {
		if (!authManager.isAdmin()) return -1L;
		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery();
		return count(query, filter);
	}

	@QueryMapping
	public List myActiveProcessInstances(@Argument String filter, @Argument Range range) {
		String currentUserId = authManager.getCurrentUserId();
		if (currentUserId == null) return Collections.emptyList();

		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
			.startedBy(currentUserId)
			.orderByStartTime().desc();

		return list(query, range, filter);
	}

	@QueryMapping
	public long myActiveProcessInstancesCount(@Argument String filter) {
		String currentUserId = authManager.getCurrentUserId();
		if (currentUserId == null) return 0L;

		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
			.startedBy(currentUserId);

		return count(query, filter);
	}

	@QueryMapping
	@PreAuthorize("isAuthenticated()")
	public ProcessInstance processInstance(@Argument String id) {
		return runtimeService.createProcessInstanceQuery()
			.processInstanceId(id)
			.singleResult();
	}

	// === mutations === //

	@MutationMapping
	@PreAuthorize("isAuthenticated()")
	public Object startProcess(@Argument String deploymentId, @Argument("id") String processDefinitionId, @Argument JsonNode values, @Argument List files) {
		LOG.info("startProcess: processDefinitionId={}, values={}", processDefinitionId, values);

		if (files != null && !files.isEmpty()) {
			LOG.info("startProcess: received files");
			for (MultipartFile file : files) {
				LOG.info("- name={}, filename={}, type={}", file.getName(), file.getOriginalFilename(), file.getContentType());
			}
		}

		try {
			return engineFacade.startProcessById(deploymentId, processDefinitionId, values, files);
		}
		catch (InputException e) {
			return e.getInputErrors();
		}
		catch (FlowableObjectNotFoundException e) {
			throw new NotFoundException("process", "id", processDefinitionId);
		}
	}

	@MutationMapping
	@PreAuthorize("isAuthenticated()")
	public Object startProcessByKey(@Argument String deploymentId, @Argument String key, @Argument JsonNode values, @Argument List files) {
		LOG.info("startProcessByKey: key={}, formValues={}", key, values);

		if (files != null && !files.isEmpty()) {
			LOG.info("startProcessByKey: received files");
			for (MultipartFile file : files) {
				LOG.info("- name={}, filename={}, type={}", file.getName(), file.getOriginalFilename(), file.getContentType());
			}
		}

		try {
			ProcessDefinition processDefinition = requireFound(
				repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionKey(key)
					.latestVersion()
					.singleResult(),
				"process definition", "key", key);

			return engineFacade.startProcessById(deploymentId, processDefinition.getId(), values, files);
		}
		catch (InputException e) {
			return e.getInputErrors();
		}
		catch (FlowableObjectNotFoundException e) {
			throw new NotFoundException("process definition", "key", key);
		}
	}

	@MutationMapping
	@PreAuthorize("isAuthenticated()")
	public Task saveStartForm(@Argument String deploymentId, @Argument String key, @Argument JsonNode values, @Argument List files) {
		LOG.info("saveStartForm: key={}, formValues={}", key, values);

		if (files != null && !files.isEmpty()) {
			LOG.info("saveStartForm: received files");
			for (MultipartFile file : files) {
				LOG.info("- name={}, filename={}, type={}", file.getName(), file.getOriginalFilename(), file.getContentType());
			}
		}

		ProcessDefinition processDefinition = requireFound(
				repositoryService
						.createProcessDefinitionQuery()
						.processDefinitionKey(key)
						.latestVersion()
						.singleResult(),
				"process definition", "key", key);

		return engineFacade.saveStartForm(deploymentId, processDefinition.getId(), values, files);
	}

	@MutationMapping
	@PreAuthorize("isAuthenticated()")
	public String stopProcess(@Argument String id, @Argument String reason) {
		LOG.info("stopProcess: id={}, reason={}", id, reason);
		try {
			runtimeService.deleteProcessInstance(id, reason);
		}
		catch (FlowableObjectNotFoundException e) {
			throw new NotFoundException("process instance", "id", id);
		}
		return id;
	}

	@MutationMapping
	public String cancelProcess(@Argument String id) {
		LOG.info("cancelProcess: id={}", id);
		engineFacade.cancelProcess(id);
		return id;
	}

	// === utility === //

	private static List list(ProcessInstanceQuery query, Range range, String filter) {
		applyFilter(query, filter);
		return range != null ? query.listPage(range.getStart(), range.getCount()) : query.list();
	}

	private static long count(ProcessInstanceQuery query, String filter) {
		applyFilter(query, filter);
		return query.count();
	}

	private static void applyFilter(ProcessInstanceQuery query, String filter) {
		if (filter != null) {
			String like = "%" + filter + "%";
			query.processInstanceNameLikeIgnoreCase(like);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy